Emergency Hotline: Call 1-844-363-1423 (United We Dream Hotline)
ICE Encounter

Why Offline Matters

Digital access fails marginalized communities:

  • Remote border areas lack cellular coverage
  • Detention facilities block internet access
  • Enforcement situations prevent phone use
  • Economic barriers limit data plans

Physical and offline maps are critical infrastructure.


Print Map Generation

The Challenge

Web maps use low-DPI tile streams optimized for screens, not print quality.

Medium Resolution
Screen 72-96 DPI
Print 300 DPI

Client-Side Export

import html2canvas from 'html2canvas';

async function exportMap(format = 'png') {
  // Temporarily increase tile quality
  map.options.zoomSnap = 0;

  const canvas = await html2canvas(
    document.getElementById('map'),
    {
      scale: 4, // 4x resolution
      useCORS: true,
      allowTaint: false
    }
  );

  // Download
  const link = document.createElement('a');
  link.download = `checkpoint-map-${Date.now()}.${format}`;
  link.href = canvas.toDataURL(`image/${format}`);
  link.click();
}

Print Stylesheet

@media print {
  /* Hide UI controls */
  .leaflet-control-zoom,
  .leaflet-control-layers,
  .map-controls {
    display: none !important;
  }

  /* Maximize map */
  #map {
    width: 100%;
    height: 100vh;
  }

  /* High contrast markers */
  .leaflet-marker-icon {
    filter: contrast(1.2);
  }

  /* Add attribution */
  .print-attribution {
    display: block;
    position: fixed;
    bottom: 10px;
    font-size: 8pt;
  }
}

Print Button UI

<div class="print-controls">
  <button onclick="window.print()">
    Print Current View
  </button>
  <button onclick="exportMap('png')">
    Download as Image
  </button>
  <button onclick="exportMap('pdf')">
    Download as PDF
  </button>
</div>

Static Map Images

For Print Materials

Generate static images without JavaScript:

<!-- Using OpenStreetMap static tiles -->
<img src="https://staticmap.openstreetmap.de/staticmap.php
  ?center=32.7,-117.1
  &zoom=10
  &size=800x600
  &markers=32.7,-117.1,red"
  alt="Map of San Diego checkpoint locations">

MapToPoster Approach

For high-quality static exports:

const poster = new MapToPoster(map, {
  width: 3300,    // 11" at 300dpi
  height: 2550,   // 8.5" at 300dpi
  format: 'png',
  title: 'Immigration Checkpoints',
  attribution: '© OpenStreetMap contributors'
});

poster.generate().then(dataUrl => {
  downloadImage(dataUrl, 'checkpoint-poster.png');
});

Offline Mobile Maps

OsmAnd Configuration

OsmAnd is a free, offline-first navigation app.

Download: Android/iOS app stores

Custom POI Import

<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="advocacy-tools">
  <metadata>
    <name>Immigration Checkpoints</name>
    <desc>Known checkpoint locations</desc>
    <time>2026-03-25T00:00:00Z</time>
  </metadata>

  <wpt lat="32.9012" lon="-116.8234">
    <name>I-8 Checkpoint (East)</name>
    <desc>Permanent. All traffic stopped. Open 24/7.</desc>
    <type>checkpoint</type>
    <extensions>
      <osmand:icon>special_trekking</osmand:icon>
      <osmand:background>circle</osmand:background>
      <osmand:color>#FF0000</osmand:color>
    </extensions>
  </wpt>

  <wpt lat="33.0234" lon="-117.1234">
    <name>Legal Aid - San Diego</name>
    <desc>Free immigration legal services. Spanish available.</desc>
    <type>legal_aid</type>
    <extensions>
      <osmand:icon>amenity_courthouse</osmand:icon>
      <osmand:background>square</osmand:background>
      <osmand:color>#00FF00</osmand:color>
    </extensions>
  </wpt>
</gpx>

Installing in OsmAnd

  1. Transfer .gpx file to device
  2. Open OsmAnd → Menu → My Places
  3. Tap + → Import
  4. Select GPX file
  5. Points appear on map

MBTiles for Offline Basemaps

What Are MBTiles?

SQLite database containing pre-rendered map tiles for offline use.

Generating MBTiles

# Using tippecanoe
tippecanoe -o region.mbtiles \
  --minimum-zoom=6 \
  --maximum-zoom=14 \
  facilities.geojson \
  checkpoints.geojson

# Using tilemaker
tilemaker --input region.osm.pbf \
          --output region.mbtiles \
          --config config.json

Serving Offline

For mobile apps that support MBTiles:

App MBTiles Support
OsmAnd Import as overlay
Locus Map Native support
AlpineQuest Native support
Avenza Maps Import support

QR Code Integration

Linking Print to Digital

<!-- On printed flyer -->
<div class="qr-section">
  <img src="/qr/offline-map-package.png"
       alt="Scan to download offline maps">
  <p>Scan to download offline checkpoint map</p>
</div>

Generating QR Codes

import QRCode from 'qrcode';

async function generateQR(url, filename) {
  const dataUrl = await QRCode.toDataURL(url, {
    width: 200,
    margin: 2,
    color: {
      dark: '#000000',
      light: '#FFFFFF'
    }
  });

  return dataUrl;
}

// Generate for offline package
const qr = await generateQR(
  'https://advocacy.org/downloads/checkpoint-map.gpx',
  'checkpoint-qr.png'
);

Print Material Design

.print-card {
  width: 3.5in;
  height: 2in;
  padding: 0.25in;
  display: flex;
}

.print-card .qr-code {
  width: 1.5in;
  height: 1.5in;
}

.print-card .instructions {
  flex: 1;
  font-size: 10pt;
  line-height: 1.3;
}

Distribution Methods

Physical Distribution

Location Method
Community centers Printed cards
Legal clinics Flyer stacks
Churches Bulletin inserts
Schools Parent packets
Community events Handouts

Digital Distribution

Method Use Case
Website download Self-service
QR code scan Print-to-digital
WhatsApp/Signal Direct sharing
USB drives Community events

File Size Considerations

Offline Package Sizes

Content Approximate Size
GPX with 100 POIs 50 KB
County MBTiles 50-200 MB
State MBTiles 500 MB - 2 GB
Region (zoom 6-14) 100-500 MB

Optimization Strategies

Strategy Reduction
Limit zoom levels 50-70%
Reduce tile area Proportional
Compress tiles 20-30%
Vector vs raster 50-80%

Keeping Offline Data Current

Version Control

{
  "package_name": "checkpoint-map",
  "version": "2026.03.25",
  "last_updated": "2026-03-25T00:00:00Z",
  "checksum": "sha256:abc123...",
  "download_url": "/downloads/checkpoints-2026-03-25.gpx"
}

Update Notification

// Check for updates on app open
async function checkForUpdates() {
  const current = localStorage.getItem('package_version');
  const response = await fetch('/api/package-info');
  const latest = await response.json();

  if (latest.version !== current) {
    showUpdatePrompt(latest);
  }
}

Printable Companions

Legend Cards

Print-ready legend for map interpretation:

<div class="print-legend">
  <h3>Map Legend</h3>
  <ul>
    <li><span class="marker red">●</span> Permanent Checkpoint</li>
    <li><span class="marker orange">●</span> Known Roving Area</li>
    <li><span class="marker green">●</span> Legal Aid Office</li>
    <li><span class="marker blue">●</span> Sanctuary Zone</li>
  </ul>
  <p class="note">Data as of March 2026</p>
</div>

Emergency Contact Cards

Include with map distributions:

<div class="contact-card">
  <h4>If Stopped by Immigration</h4>
  <ul>
    <li>Stay calm</li>
    <li>You have the right to remain silent</li>
    <li>Don't sign anything</li>
  </ul>
  <p><strong>Legal Hotline:</strong> 1-800-XXX-XXXX</p>
</div>

Related Resources