Shapefiles are a proprietary but common geospatial file format developed by ESRI. They are frequently used by governments to store geospatial data.
Many shapefiles can be easily uploaded into an XYZ space. Some require extra steps before you can bring them into XYZ.
In this tutorial, we cover what you need to do to successfully import shapefiles, along with special steps using other open source tools for those trickier ones.
This document assumes:
You should also install - mapshaper - QGIS and the HERE XYZ QGIS plugin.
Unlike a GeoJSON file, a shapefile is made up of a number of separate files. Shapefiles on the internet are usually zipped, but once uncompressed you will see a number of files with the same name but different extensions. Some of the more important ones are:
If the shapefile uses lat/lon coordinates and the WGS84 projection, and is under 200MB, you should be able to upload it using the Data Hub CLI.
In the terminal, cd to the shapefile directory, and type:
here xyz upload space_id -f my_shapefile.shp
The Data Hub CLI looks for my_shapefile.dbf and other files in the specified directory. (If it is missing, no attributes of the geometries will be imported.)
Note: You can use -a to select attributes of features to convert into tags, which lets you filter features server-side when you access the XYZ Hub API.
Shapefiles are an infinitely variable format, and there will be cases where you may need to manipulate or modify the data in order to import it into your XYZ space. You can do this with other open-source geospatial tools, specifically mapshaper and QGIS.
The mapshaper is a powerful command-line tool for editing and manipulating geospatial data in a variety of common formats.
You can install mapshaper using npm:
npm install -g mapshaper
Note: mapshaper can modify shapefiles directly, or convert shapefiles into GeoJSON. Converting to GeoJSON gives you more options and faster uploads when bringing the data into XYZ. The mapshaper documentation provides a wide variety of options, but a simple conversion command is:
mapshaper my_geodata.shp -o my_geodata.geojson here xyz upload spaceID -f my_geodata.geojson -a
-a lets you interactively pick property values to convert into tags. You can use -s to stream the file and upload it much more quickly, but in this case you need to specify the property keys with -p.
here xyz upload spaceID -f my_geodata.geojson -p property_name -s
Depending on the size of the shapefile you may be able to pipe the GeoJSON from mapshaper directly to the Data Hub CLI, using the - option in mapshaper:
mapshaper my_geodata.shp -o format=geojson - | here xyz upload spaceID -a -t specific_tag
You can also stream it:
mapshaper my_geodata.shp -o format=geojson - | here xyz upload spaceID -p property_name -t specific_tag -s
(If you see unusual errors when piping from mapshaper to XYZ, you may have more success keeping the conversion and uploading as separate steps.) HERE XYZ QGIS plugin¶
QGIS is an open-source desktop GIS tool that lets you edit, visualize, manage, analyze and convert geospatial data. You can upload and download data from your XYZ spaces using the HERE XYZ QGIS plugin. (The plugin is also available on Github.)
You can install the HERE XYZ QGIS plugin from within QGIS Plugin search tool if you have the "show experimental plugins" option checked in the plugin console settings.
You can easily open almost any shapefile in QGIS, at which point you can save it to your XYZ spaces using the HERE XYZ QGIS plugin, or export it as GeoJSON to the desktop to use the Data Hub CLI streaming upload options.
Some shapefiles may contain very large and extremely detailed individual lines or polygons. If a single feature is greater than 10-20MB, you may see 400 or 413 http errors when you try to upload the shapefile. In many cases, this level of detail is unnecessary for web mapping. If so, you can try to simplify the feature using mapshaper or QGIS. You may also want to adjust Data Hub CLI upload parameters so that less data is sent in each API request.
To optimize upload speed, the Data Hub CLI "chunks" features together and then sends the chunk to the API. There are typically 200-400 features per chunk. While a large feature may be small enough to be uploaded, when combined with other features, the chunk may be too large for the API.
You can adjust the chunk size using -c -- in this example, the Data Hub CLI uploads 100 features per API request:
here xyz upload spaceID -f large_features.shapefile -c 100
Depending on the size of the feature, you may want to try c -10 (ten per request) or even c -1 (which would load one feature at a time).
You can simplify lines and polygons in shapefiles using -simplify.
mapshaper very_large_features.shp -simplify dp 20% -o simplified_features.geojson
Depending on the zoom level and extent your web map, you can also try 10%, 5%, and 1%.
More information on simplification is available here:
For smaller shapefiles, you can pipe output from mapshaper directly to the Data Hub CLI, accelerating your TTM (Time To Map).
mapshaper big_shapefile.shp -o format=geojson - | here xyz upload spaceID -p property_name -t specific_tag -s
Note: The Simplify tool works in decimal degree and the default is 1 degree, which is probably not what you want. Useful values depend on the extent and zoom levels of your map, but 0.01, 0.001, 0.0001, and 0.00001 are interesting values.
The HERE attempts to load the entire shapefile into memory before uploading it to the API. This generally works for shapefiles up to 200 MB, but you may see Node.js memory errors beyond that.
While GeoJSON and CSVs can be streamed via the upload -s option, this option is not yet available for shapefiles. You will have the most success converting the shapefile to GeoJSON and then uploading to XYZ.
mapshaper big_data.shp -o format=geojson big_data.geojson here xyz upload spaceID -f big_data.geojson -s
Note: that -a is not available when -s is used, but you can still specify properties to convert into tags using -p.
You can also open the very large shapefile in QGIS and save directly to an XYZ space using the XYZ QGIS plugin, though this will be slower than using the Data Hub CLI streaming feature as the QGIS plugin is not multi-threaded.
There are many projections to choose from. GeoJSON expects points to be projected in Web Mercator (WGS84/EPSG:4326). Many shapefiles are in different projections, or use local projections without lat/lon coordinates (i.e., state plane). You can convert mapshaper into GeoJSON-friendly coordinates.
mapshaper different_projection.shp -proj wgs84 -o format=geojson - | here xyz upload spaceID -p property_name -t specific_tag -s
If you see any node.js memory errors, you can break it up into two steps:
mapshaper different_projection.shp -proj wgs84 -o format=geojson different_projection.geojson here xyz upload spaceID -f different_projection.geojson