You want to put your data on a searchable, filterable map. Provide a comma separated file (CSV) and this free, open source template will do the rest. This template is a successor to Derek Eder's Fusion Tables Map Template.
- address search (with variable radius and geocomplete)
- results count
- powered by Turfjs and plain ol' javascript
- map and list view modes
- large info windows when clicking on a point
- easy customization of hover, popup and table views
- RESTful URLs for sharing searches
- ability to easily add additional search filters (checkboxes, sliders, etc)
- mobile and tablet friendly using responsive design (Bootstrap 4)
- built with HTML, CSS and Javascript - no server side code required
This template depends on other JS libraries and resources:
- Bootstrap 4 - Responsive CSS and HTML framework
- Leaflet - Rendering the interactive map
- Turf.js - Geospatial filtering
- Google Maps Javscript API - Geocoding and the Places API
- leaflet-color-markers - A set of colored map markers
- csv-to-geojson - Converts CSV files to GeoJSON
- jQuery 3.3.1 - Javascript utility
- jQuery Address - For stateful URLs
- Moment.js - Manipulating dates and times in javascript
This template borrows heavily from Derek Eder's Fusion Tables Map Template and follows a similar code pattern and architecture. It is intended to be easy to pick up and modify by people with limited coding experience and not require anything to be installed on your computer or server to run it.
That being said, there are some differences between this template and the Fusion Tables Map Template, namely:
- Powered by Turf.js instead of Fusion Tables. This map has no back-end service powering it. It's all done in the browser with the help of Turf.js.
- Using Bootstrap 4. I upgraded to the latest version of Boostrap when building this template. There are some notable changes in syntax with these versions, which are documented here.
- List view included by default. I decided to include the list view mode by default, as it is the best way to view results on a mobile phone. It requires editing an additonal template
templates/table-row.ejs
but I think is worth the extra work to customize. - Hover functionality. Because it was pretty to do in Leaflet, this template includes the ability to hover over a point and see a preview of the point data before clicking on it.
- Data size limits. Because this template loads all the data into your browser, there are limitations to how any points you can display. Showing more than a 1,000 points may make your browser quite slow.
Follow the steps below and you'll be in business with your own map.
This template will work with data in csv and geojson formats.
If you have an xls
or xlsx
spreadsheet, you can save it as a csv
file from Excel, Numbers, Libre Office or your spreadsheet tool of choice.
The csv
file must have a latitude column and longitude column and all rows must be geocoded. If you don't have this, but have information like a street address, you'll need to geocode your data.
Here's a few tools for geocoding:
- Google has the best geocoder in terms of accuracy. They have an API that you can use, but may cost you money depending on how many rows you have to geocode.
- To geocode addresses inside Google Sheets, install the free Geocoding by SmartMonkey Add-On for Google Sheets. See geocoding instructions in Hands-On Data Visualization.
- Geocoding in QGIS (uses OpenStreetMap)
- BatchGeo
- Texas A&M
- Download or clone this project and fire up your text editor of choice. Open up
/js/map.js
and set your map options in theSearchableMapLib.initialize
function:
map_centroid
- the lat/long you want your map to center on (find yours here)filePath
- Path to your map data file. This file needs to be in csv or geojson format and placed in thedata
folder. This file's first line must be the header, and it must have a latitude column and longitude column.fileType
- Set if you are loading in acsv
orgeojson
file
- Edit the templates in the
templates
folder for how you want your data displayed. These templates use EJS, which allows the display of your variables with HTML, as well as conditional logic. Documentation is here.
/templates/hover.ejs
- template for when you hover over a dot on the map/templates/popup.ejs
- template for when a dot on the map is clicked/templates/table-row.ejs
- template for each row in the list view
- Remove the custom filters and add your own.
index.html
- custom HTML for filters starts around line 112/js/searchable_map_lib.js
- logic for custom filters starts around line 265
Once you've made your changes, you'll want to test the map to make sure it works. To view it in your browser, you'll need to run a web server on your computer. It can be any web server, but here are some ones I suggest using:
- HTTP Party's http-server. Once its installed, you can run
npx http-server . -c-1
from the command line. - If you have python installed, you can run this from the command line (note, you can see what version of python you have by typing `python --version):
- python 2:
python -m SimpleHTTPServer
- python 3:
python -m http.server
- python 2:
- If you have one you'd like to add to this list (especially one for Windows machines, please add a comment to this issue)
If your map isn't displaying any data, try the following:
- Set the
debug
option in SearchableMapLib.initialize totrue
. - Use the Firefox page inspector or Chrome DevTools. This will allow you to view and debug your javascript.
- Load your map in the browser and open the javascript console
- Chrome DevTools on a Mac: Option+Command+J
- Chrome DevTools on a PC: Control+Shift+J
- Firefox Page Inspector: Tools => Web Developer => Web Console)
- If you do see javascript errors:
- The error will tell you what line it is failing on. Best to start by going there!
- Columns you reference from your CSV file are case sensitive and must be exaclty the same.
- Before you publish, you'll need to get a Google API key. You can get on here. Replace the API key on this line of
index.html
with yours:<script type="text/javascript" src="https://maps.google.com/maps/api/js?libraries=places&key=[YOUR KEY HERE]"></script>
- Upload this map and all the supporting files and folders to your site. This map requires no back-end code, so any host will work, including GitHub pages, Netlify or your own web server.
You can configure your map by passing in a dictionary of options when you call the SearchableMapLib.initialize
function in /js/map.js
. Here's an example:
SearchableMapLib.initialize({
filePath: 'data/chicago-flu-shot-locations-2019.csv',
fileType: 'csv',
recordName: 'flu shot location',
recordNamePlural: 'flu shot locations',
map_centroid: [41.85754, -87.66231],
defaultZoom: 11,
defaultRadius: 1610,
debug: false,
});
Option | Default value | Notes |
---|---|---|
map_centroid | [41.881832, -87.623177] | Center [latitude, longitude] that your map shows when it loads. Defaults to Chicago. |
defaultZoom | 9 | Default zoom level when map is loaded (bigger is more zoomed in). |
defaultRadius | 805 | Default search radius. Defined in meters. Default is 1/2 mile. |
filePath | The path to your csv or geojson file that contains your map data. This file should be put in the data directory | |
fileType | csv | File type to load in. Supports csv or geojson |
recordName | record | Used for showing the count of results. |
recordNamePlural | records | |
debug | false | Used to turn on helpful messages when debugging (see section on Debugging - common issues/troubleshooting) |
For making customizations to this template
If something is not behaving intuitively, it is a bug, and should be reported. Report it here: https://github.com/datamade/searchable-map-template-turf/issues