UNPKG

@mapbox/geojson-mapnikify

Version:

transform geojson with simplestyle-spec into mapnik xml

120 lines (98 loc) 3.33 kB
var normalize = require('@mapbox/geojson-normalize'), makizushi = require('@mapbox/makizushi'), queue = require('queue-async'), path = require('path'), fs = require('fs'), sigmund = require('sigmund'), enforceDefaults = require('./lib/defaults.js'), normalizeStyle = require('./lib/normalizestyle.js'), cachepath = require('./lib/cachepath.js'), loadURL = require('./lib/urlmarker.js'), get = require('./lib/get.js'); var template = fs.readFileSync(__dirname + '/lib/template.xml', 'utf8'); module.exports = generateXML; function generateXML(data, retina, callback) { var gj = normalize(data), q = queue(1); if (!gj) return callback(new Error('invalid GeoJSON')); for (var i = 0; i < gj.features.length; i++) { gj.features[i] = !markerURL(gj.features[i]) ? enforceDefaults(normalizeStyle(gj.features[i])) : normalizeStyle(gj.features[i]); } gj.features.filter(isPoint).forEach(function(feat, i) { if (markerURL(feat)) { q.defer(getRemote, feat, retina); } else { q.defer(getMarker, feat, retina); } }); q.awaitAll(done); function done(err, ls) { if (err) return callback(err); return callback(null, template.replace('{{geojson}}', JSON.stringify(gj))); } } function getRemote(feature, retina, callback) { var path = cachepath(markerURL(feature) + feature.properties['marker-color']) + '.png'; var written = function(err) { if (err) return callback(err); feature.properties['marker-path'] = path; callback(null, path); }; fs.exists(path, function(exists) { if (exists) { return written(null); } else { loadURL(feature, function urlLoaded(err, data) { if (err) return callback(err); fs.writeFile(path, data, written); }); } }); } function getMarker(feature, retina, callback) { var fp = feature.properties || {}, size = fp['marker-size'][0], symbol = fp['marker-symbol'] ? fp['marker-symbol'] : '', color = fp['marker-color'].replace('#', ''); var options = { tint: color, base: 'pin', symbol: symbol, retina: retina, size: size }; var path = cachepath(JSON.stringify(options)) + '.png'; fs.exists(path, function(exists) { if (exists) { feature.properties['marker-path'] = path; return callback(null, path); } else { makizushi(options, rendered); } }); function rendered(err, data) { if (err) return callback(err); fs.writeFile(path, data, written); } function written(err) { if (err) { return callback(err); } else { feature.properties['marker-path'] = path; callback(null, path); } } } function isPoint(feature) { return feature.geometry && (feature.geometry.type === 'Point' || feature.geometry.type === 'MultiPoint'); } function markerURL(feature) { return (feature.properties || {})['marker-url']; } function setRequestClient(requestClient){ get.requestClient = requestClient; } module.exports.setRequestClient = setRequestClient;