A real-time, crowdsourced livestock location tracker built with Cloudflare Workers.
PigMap.org is a web application that allows users in the USA to anonymously report and track livestock sightings in real-time. The application uses a map interface to display reported sightings, allowing users to:
- View recent livestock sightings
- Report new livestock sightings with details and media
- Receive real-time updates as new sightings are reported
- Access the site in 17 different languages
- Fully anonymous reporting of livestock sightings (no IP addresses or personal data stored)
- Real-time updates via WebSockets
- Media upload capabilities (photos/videos)
- Proximity-based sorting of reports
- Multilingual interface with support for 17 languages
- Mobile-friendly, accessible interface
- Right-to-left (RTL) language support
- Keyboard navigation and screen reader accessibility
PigMap.org is built with:
- Frontend: Leaflet.js for mapping, with vanilla JavaScript
- Backend: Cloudflare Workers
- Storage:
- Cloudflare D1 (SQLite database) for structured data
- Cloudflare R2 for media storage (images/videos)
- Cloudflare KV for configuration
- Real-time Updates: Cloudflare Durable Objects and WebSockets
- Node.js and npm
- Cloudflare account with Workers, R2, KV, and D1 access
- Install dependencies:
npm install
-
Update the wrangler.toml file with your Cloudflare account details:
- R2 bucket IDs
- KV namespace IDs
- D1 database IDs
-
Start the local development server:
npm run dev
There's a small helper script that applies the SQL migration files against a temporary SQLite database and verifies the expected tables and columns exist. This is useful to sanity-check D1 migrations before deploying.
Run it with:
node scripts/verify_migrations.js
Rate limiting and configuration
- PigMap uses a KV namespace (suggested name:
PIGMAP_RATE_LIMIT
) for short-lived rate-limiting counters. Bind it inwrangler.toml
asPIGMAP_RATE_LIMIT
. - Optionally set
RATE_LIMIT_SALT
(secret) in your environment/Secret to make hashed identifiers harder to guess. Bind as an environment variable in your Worker.
Docker-based exact migration test
If you want to execute the migrations exactly as D1 would, use the included Docker helper which runs sqlite3 and prints schema information:
# Build container (one-time)
docker build -t pigmap-migrate -f docker/Dockerfile .
# Run the migration verifier
docker run --rm -v "$PWD":/work -w /work pigmap-migrate /bin/bash -c "./docker/run_migrations.sh"
Deploy to Cloudflare Workers:
npm run deploy
The application is deployed to Cloudflare Workers and can be accessed at:
- pigmap.org - Main domain
- kc.pigmap.org - Kansas City, MO region
- kcmo.pigmap.org - Kansas City, MO region (alternate)
- kansascity.pigmap.org - Kansas City, MO region (alternate)
PigMap supports the following languages:
- English
- Spanish (Español)
- Haitian Creole (Kreyòl Ayisyen)
- Chinese (中文)
- Vietnamese (Tiếng Việt)
- Arabic (العربية)
- Amharic (አማርኛ)
- Swahili (Kiswahili)
- Somali (Soomaali)
- Farsi (فارسی)
- French (Français)
- Nepali (नेपाली)
- Karen
- Burmese (မြန်မာဘာသာ)
- Portuguese (Português)
- Urdu (اردو)
- Kurdish (Kurdî)
MIT
Deploy to Cloudflare Workers:
npm run deploy
The application uses Cloudflare D1 (SQLite) with the following schema:
- reports: Stores livestock sighting reports
- media: Stores references to media files in R2
Notes:
- Media uploads are limited to 5MB per file by default. This is enforced by the Worker in
src/index.js
. - Allowed media content types: image/jpeg, image/png, image/gif, image/webp, video/mp4, video/quicktime, video/webm.
- Geolocation: Find user's current location
- Real-time Updates: WebSocket-based live updates of new reports
- Media Uploads: Support for image and video uploads
- Proximity Sorting: Show nearest sightings first
- Time-based Rendering: Older reports fade out over time
This project is licensed under the MIT License - see the LICENSE file for details.
For questions or support, please contact admin@pigmap.org
PigMap.org is designed with privacy as a core principle:
- No IP Addresses: We do not store IP addresses or any personally identifiable information
- Anonymous Contributions: All reports and comments are completely anonymous
- Minimal Data Collection: Only the information explicitly provided by users is stored
- Media Privacy: Uploaded media is stored without any metadata that could identify the source
- No Analytics: We don't use any third-party analytics or tracking
If you want to clear any existing IP data from your deployment, run:
npx wrangler d1 execute LIVESTOCK_DB --file=./clear_ip_data.sql