├── .gitignore ├── .github └── FUNDING.yml ├── src ├── split.js ├── decompress.js ├── decode.js ├── compress.js ├── makejs.js ├── merge.js ├── shaper2echarts.js ├── property.js ├── parseGeoJson.js ├── map-tool.js └── maker.js ├── CHANGELOG.md ├── package.json └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .DS_Store 3 | node_modules 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: chfw 4 | patreon: chfw 5 | 6 | -------------------------------------------------------------------------------- /src/split.js: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env node 2 | 3 | var program = require('commander'); 4 | const maker = require('./maker'); 5 | 6 | program 7 | .arguments('') 8 | .action(function(geojson){ 9 | maker.splitAsGeojson(geojson); 10 | }) 11 | .parse(process.argv); 12 | -------------------------------------------------------------------------------- /src/decompress.js: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env node 2 | 3 | var program = require('commander'); 4 | const maker = require('./maker'); 5 | 6 | program 7 | .arguments(' ') 8 | .action(function(js, geojson){ 9 | maker.decompress(js, geojson); 10 | }) 11 | .parse(process.argv); 12 | -------------------------------------------------------------------------------- /src/decode.js: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env node 2 | 3 | var program = require('commander'); 4 | const maker = require('./maker'); 5 | 6 | program 7 | .arguments(' ') 8 | .action(function(js, geojson){ 9 | maker.decode(js, geojson); 10 | }) 11 | .parse(process.argv); 12 | -------------------------------------------------------------------------------- /src/compress.js: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env node 2 | 3 | var program = require('commander'); 4 | const maker = require('./maker'); 5 | 6 | program 7 | .arguments(' ') 8 | .action(function(geojson, output){ 9 | maker.compress(geojson, output); 10 | }) 11 | .parse(process.argv); 12 | -------------------------------------------------------------------------------- /src/makejs.js: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env node 2 | 3 | var program = require('commander'); 4 | const maker = require('./maker'); 5 | 6 | program 7 | .arguments(' ') 8 | .action(function(geojson, js, mapRegistryName){ 9 | maker.makeJs(geojson, js, mapRegistryName); 10 | }) 11 | .parse(process.argv); 12 | -------------------------------------------------------------------------------- /src/merge.js: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env node 2 | const fs = require('fs'); 3 | 4 | var program = require('commander'); 5 | const maker = require('./maker'); 6 | 7 | 8 | program 9 | .arguments(' ') 10 | .action(function(geojson, geojsonToBeMerged){ 11 | maker.merge(geojson, geojsonToBeMerged); 12 | }) 13 | .parse(process.argv); 14 | -------------------------------------------------------------------------------- /src/shaper2echarts.js: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env node 2 | const fs = require('fs'); 3 | const maker = require('./maker'); 4 | var program = require('commander'); 5 | 6 | program 7 | .arguments(' ') 8 | .action(function(geojson, geojson4echarts, name){ 9 | maker.transform(geojson, geojson4echarts, name); 10 | }) 11 | .parse(process.argv); 12 | -------------------------------------------------------------------------------- /src/property.js: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env node 2 | 3 | var program = require('commander'); 4 | const maker = require('./maker'); 5 | 6 | program 7 | .arguments('') 8 | .option('-l, --list', 'list all properties in each feature') 9 | .option('-r, --rename ', 'rename a property') 10 | .option('-m, --merge ', 'merge two property') 11 | .action(function(geojson){ 12 | if(program.list){ 13 | maker.inspect(geojson); 14 | }else if(program.rename){ 15 | var args = program.rename.split(','); 16 | var oldname = args[0]; 17 | var newname = args[1]; 18 | maker.rename(geojson, oldname, newname); 19 | }else if(program.merge){ 20 | var args = program.merge.split(','); 21 | var propertyA = args[0]; 22 | var propertyB = args[1]; 23 | var newProperty = args[2]; 24 | maker.mergeProperty(geojson, propertyA, propertyB, newProperty); 25 | } 26 | }) 27 | .parse(process.argv); 28 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change log 2 | 3 | ## 1.0.14 - 27.5.2019 4 | 5 | 1. fix 'split', 'remove' commands, where were not working 6 | 1. bug fix decompress command so that it can decompress minified js file 7 | 1. new 'decode' command to decode utf-8 encoding geojson file 8 | 9 | ## 1.0.12 - 9.1.2019 10 | 11 | 1. More commands: transform, remove, merge a property. 12 | 13 | ## 1.0.11 - 4.3.2018 14 | 15 | 1. Updated merge command to merge all of the 2nd geojson to the first one. 16 | 17 | ## 1.0.10 - 28.12.2017 18 | 19 | 1. added the capability to cut a hole from an existing feature from another one. 20 | 2. updated merge function to remove existing feature if the feature to be 21 | merged exists already 22 | 23 | ## 1.0.9 - 24.12.2017 24 | 25 | 1. old compress becomes makejs 26 | 2. new compress does compression only 27 | 28 | ## 1.0.4 - 24.09.2017 29 | 30 | 1. decomporess command is delivered 31 | 2. merge geojson 32 | 3. convert mapshaper output into echarts compatible map 33 | 34 | ## 1.0.2 - 24.09.2017 35 | 36 | 1. comporess command is delivered 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "echarts-mapmaker", 3 | "version": "1.1.0", 4 | "description": "Make maps for echarts", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "bin": { 9 | "makejs": "./src/makejs.js", 10 | "compress": "./src/compress.js", 11 | "property": "./src/property.js", 12 | "decompress": "./src/decompress.js", 13 | "merge": "./src/merge.js", 14 | "split": "./src/split.js", 15 | "decode": "./src/decode.js", 16 | "shaper2echarts": "./src/shaper2echarts.js" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/chfw/echarts-mapmaker.git" 21 | }, 22 | "keywords": [ 23 | "echarts" 24 | ], 25 | "author": "C.W.", 26 | "license": "ISC", 27 | "bugs": { 28 | "url": "https://github.com/chfw/echarts-mapmaker/issues" 29 | }, 30 | "homepage": "https://github.com/chfw/echarts-mapmaker#readme", 31 | "dependencies": { 32 | "commander": "^2.11.0", 33 | "pinyin": "^2.8.3" 34 | }, 35 | "devDependencies": { 36 | "mocha": "^4.0.1", 37 | "nyc": "^11.3.0", 38 | "sinon": "^4.1.2" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/parseGeoJson.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Parse and decode geo json 3 | * @module echarts/coord/geo/parseGeoJson 4 | */ 5 | 6 | 'use strict'; 7 | 8 | function decode(json) { 9 | if (!json.UTF8Encoding) { 10 | return json; 11 | } 12 | var encodeScale = json.UTF8Scale; 13 | if (encodeScale == null) { 14 | encodeScale = 1024; 15 | } 16 | 17 | var features = json.features; 18 | 19 | for (var f = 0; f < features.length; f++) { 20 | var feature = features[f]; 21 | var geometry = feature.geometry; 22 | var coordinates = geometry.coordinates; 23 | var encodeOffsets = geometry.encodeOffsets; 24 | 25 | for (var c = 0; c < coordinates.length; c++) { 26 | var coordinate = coordinates[c]; 27 | 28 | if (geometry.type === 'Polygon') { 29 | coordinates[c] = decodePolygon(coordinate, encodeOffsets[c], encodeScale); 30 | } else if (geometry.type === 'MultiPolygon') { 31 | for (var c2 = 0; c2 < coordinate.length; c2++) { 32 | var polygon = coordinate[c2]; 33 | coordinate[c2] = decodePolygon(polygon, encodeOffsets[c][c2], encodeScale); 34 | } 35 | } 36 | } 37 | } 38 | // Has been decoded 39 | json.UTF8Encoding = false; 40 | return json; 41 | } 42 | 43 | function decodePolygon(coordinate, encodeOffsets, encodeScale) { 44 | var result = []; 45 | var prevX = encodeOffsets[0]; 46 | var prevY = encodeOffsets[1]; 47 | 48 | for (var i = 0; i < coordinate.length; i += 2) { 49 | var x = coordinate.charCodeAt(i) - 64; 50 | var y = coordinate.charCodeAt(i + 1) - 64; 51 | // ZigZag decoding 52 | x = x >> 1 ^ -(x & 1); 53 | y = y >> 1 ^ -(y & 1); 54 | // Delta deocding 55 | x += prevX; 56 | y += prevY; 57 | 58 | prevX = x; 59 | prevY = y; 60 | // Dequantize 61 | result.push([x / encodeScale, y / encodeScale]); 62 | } 63 | 64 | return result; 65 | } 66 | 67 | module.exports = { 68 | decode: decode 69 | } 70 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # echarts-mapmaker 2 | 3 | Makes custom geomaps for echarts presentation. It takes a subset of [echarts-map-tool](https://github.com/ecomfe/echarts-map-tool) as core map editing utility. 4 | 5 | ## Tutorials 6 | 7 | :book:[echarts geomapping book](https://echarts-maps.github.io/echarts-geomapping-book-en/) 8 | :secret:[echarts 工匠秘籍](https://echarts-maps.github.io/echarts-geomapping-book-zh/) 9 | 10 | ## Commands 11 | 12 | ### makejs 13 | 14 | Compress any un-compressed geojson as js file. 15 | 16 | ``` 17 | Usage: makejs [options] 18 | 19 | 20 | Options: 21 | 22 | -h, --help output usage information 23 | ``` 24 | 25 | where importantly `mapRegistryName` is the name to be called in your echarts script. 26 | 27 | Example commands 28 | 29 | makejs [world.json](https://github.com/ecomfe/echarts/blob/master/map/json/world.json) world.js world 30 | 31 | ### compress 32 | 33 | Compress any un-compressed geojson as js file. 34 | 35 | ``` 36 | Usage: compress [options] 37 | 38 | 39 | Options: 40 | 41 | -h, --help output usage information 42 | ``` 43 | 44 | Example commands 45 | 46 | compress [world.json](https://github.com/ecomfe/echarts/blob/master/map/json/world.json) world.json 47 | 48 | ### decompress 49 | 50 | Decompress any compressed js file back to geojson 51 | 52 | ``` 53 | 54 | Usage: decompress 55 | 56 | Options: 57 | 58 | -h, --help output usage information 59 | ``` 60 | 61 | 62 | ### property 63 | 64 | Manage the property of a geojson file. 65 | 66 | ``` 67 | Usage: property [options] 68 | 69 | 70 | Options: 71 | 72 | -l, --list list all properties in each feature 73 | -r, --rename rename a property 74 | -m, --merge merge two property 75 | -h, --help output usage information 76 | ``` 77 | 78 | ### merge 79 | 80 | Merge second geojson into the first file. 81 | 82 | ``` 83 | Usage: merge [options] 84 | 85 | 86 | Options: 87 | 88 | -h, --help output usage information 89 | ``` 90 | 91 | ### split 92 | 93 | Split the geojson into individual independent geojson files 94 | 95 | ``` 96 | Usage: split [options] 97 | 98 | 99 | Options: 100 | 101 | -h, --help output usage information 102 | ``` 103 | 104 | ### decode 105 | 106 | Decode utf-8 encode geojson file 107 | 108 | ``` 109 | 110 | Usage: decode [options] 111 | 112 | 113 | Options: 114 | 115 | -h, --help output usage information 116 | ``` 117 | 118 | ### shaper2echarts 119 | 120 | Convert [mapshaper](https://github.com/mbloch/mapshaper) dissovled geojson files into echarts map file. 121 | 122 | ``` 123 | Usage: shaper2echarts [options] 124 | 125 | 126 | Options: 127 | 128 | -h, --help output usage information 129 | ``` 130 | 131 | ## License 132 | 133 | MIT 134 | 135 | This projects is NOT associated with official Apache ECharts (incubating) project and is independently maintained by [@chfw](https://github.com/chfw). 136 | 137 | ## Credit 138 | 139 | 1. compress.js comes from echarts-map-tool. 140 | 1. parseGeoJson.js comes from echarts.js. 141 | -------------------------------------------------------------------------------- /src/map-tool.js: -------------------------------------------------------------------------------- 1 | function compress(json) { 2 | 3 | json.UTF8Encoding = true; 4 | 5 | var features = json.features; 6 | if (!features) { 7 | return; 8 | } 9 | features.forEach(function (feature){ 10 | var encodeOffsets = feature.geometry.encodeOffsets = []; 11 | var coordinates = feature.geometry.coordinates; 12 | if (feature.geometry.type === 'Polygon') { 13 | coordinates.forEach(function (coordinate, idx){ 14 | coordinates[idx] = encodePolygon( 15 | coordinate, encodeOffsets[idx] = [] 16 | ); 17 | }); 18 | } else if(feature.geometry.type === 'MultiPolygon') { 19 | coordinates.forEach(function (polygon, idx1){ 20 | encodeOffsets[idx1] = []; 21 | polygon.forEach(function (coordinate, idx2) { 22 | coordinates[idx1][idx2] = encodePolygon( 23 | coordinate, encodeOffsets[idx1][idx2] = [] 24 | ); 25 | }); 26 | }); 27 | } 28 | }); 29 | 30 | return json; 31 | } 32 | 33 | function encodePolygon(coordinate, encodeOffsets) { 34 | 35 | var result = ''; 36 | 37 | var prevX = quantize(coordinate[0][0]); 38 | var prevY = quantize(coordinate[0][1]); 39 | // Store the origin offset 40 | encodeOffsets[0] = prevX; 41 | encodeOffsets[1] = prevY; 42 | 43 | for (var i = 0; i < coordinate.length; i++) { 44 | var point = coordinate[i]; 45 | result+=encode(point[0], prevX); 46 | result+=encode(point[1], prevY); 47 | 48 | prevX = quantize(point[0]); 49 | prevY = quantize(point[1]); 50 | } 51 | 52 | return result; 53 | } 54 | 55 | function quantize(val) { 56 | return Math.ceil(val * 1024); 57 | } 58 | 59 | function encode(val, prev){ 60 | // Quantization 61 | val = quantize(val); 62 | // var tmp = val; 63 | // Delta 64 | val = val - prev; 65 | 66 | if (((val << 1) ^ (val >> 15)) + 64 === 8232) { 67 | //WTF, 8232 will get syntax error in js code 68 | val--; 69 | } 70 | // ZigZag 71 | val = (val << 1) ^ (val >> 15); 72 | // add offset and get unicode 73 | return String.fromCharCode(val+64); 74 | // var tmp = {'tmp' : str}; 75 | // try{ 76 | // eval("(" + JSON.stringify(tmp) + ")"); 77 | // }catch(e) { 78 | // console.log(val + 64); 79 | // } 80 | } 81 | 82 | var specialArea = { 83 | 中国七大区: { 84 | '南海诸岛': { // 把海南诸岛加移到中国台湾右边 85 | left: 126, 86 | top: 20, 87 | width: 10 88 | } 89 | }, 90 | '美国': { 91 | Alaska: { // 把阿拉斯加移到美国主大陆左下方 92 | left: -131, 93 | top: 25, 94 | width: 15 95 | }, 96 | Hawaii: { 97 | left: -110, // 夏威夷 98 | top: 28, 99 | width: 5 100 | }, 101 | 'Puerto Rico': { // 波多黎各 102 | left: -76, 103 | top: 26, 104 | width: 2 105 | } 106 | }, 107 | '法国': { 108 | 'Guadeloupe': { 109 | left: -4.8, 110 | top: 37, 111 | width: 1 112 | }, 113 | 'Martinique': { 114 | left: -1, 115 | top: 37, 116 | width: 1 117 | }, 118 | 'French Guiana': { 119 | left: 3.2, 120 | top: 37, 121 | width: 2 122 | }, 123 | 'Mayotte': { 124 | left: 9, 125 | top: 37, 126 | width: 1 127 | }, 128 | 'Réunion': { 129 | left: 11, 130 | top: 37, 131 | width: 1.5 132 | } 133 | } 134 | }; 135 | 136 | 137 | // 不压缩,下载地图文件 138 | function makeJs(geojson, mapName) { 139 | 140 | var specialAreaArrangements = ""; 141 | if (mapName in specialArea){ 142 | var arrangement = specialArea[mapName]; 143 | specialAreaArrangements = "," + JSON.stringify(arrangement); 144 | } 145 | return "(function (root, factory) {" 146 | + "if (typeof define === 'function' && define.amd) {" 147 | + "define(['exports', 'echarts'], factory);" 148 | + "} else if (typeof exports === 'object' " 149 | + "&& typeof exports.nodeName !== 'string') {" 150 | + "factory(exports, require('echarts'));" 151 | + "} else {" 152 | + "factory({}, root.echarts);" 153 | + "}" 154 | + "}(this, function (exports, echarts) {" 155 | + "var log = function (msg) {" 156 | + "if (typeof console !== 'undefined') {" 157 | + "console && console.error && console.error(msg);" 158 | + "}" 159 | + "};" 160 | + "if (!echarts) {" 161 | + "log('ECharts is not Loaded');" 162 | + "return;" 163 | + "}" 164 | + "if (!echarts.registerMap) {" 165 | + "log('ECharts Map is not loaded');" 166 | + "return;" 167 | + "}" 168 | + "echarts.registerMap('" + mapName + "', " 169 | + JSON.stringify(geojson) + specialAreaArrangements +");}));"; 170 | 171 | } 172 | 173 | module.exports = { 174 | compress: compress, 175 | makeJs: makeJs 176 | } 177 | -------------------------------------------------------------------------------- /src/maker.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const os = require('os'); 3 | const path = require('path'); 4 | const pinyin = require('pinyin'); 5 | const mapTool = require('./map-tool'); 6 | const parser = require('./parseGeoJson'); 7 | 8 | var removeAFeature = (jsonFile, featureName) => { 9 | 10 | data = fs.readFileSync(jsonFile, 'utf8'); 11 | 12 | var geojson = JSON.parse(data); 13 | geojson.features = geojson.features.filter((feature)=>{ 14 | return feature.properties.name !== featureName; 15 | }); 16 | 17 | fs.writeFileSync("removed_"+path.basename(jsonFile), JSON.stringify(geojson)); 18 | 19 | }; 20 | 21 | var cutAHoleInFeatureAWithFB = (jsonFile, featureA, featureB) => { 22 | 23 | data = fs.readFileSync(jsonFile, 'utf8'); 24 | 25 | var geojson = JSON.parse(data); 26 | var featurea = geojson.features.find(feature => feature.properties.name === featureA); 27 | var featureb = geojson.features.find(feature => feature.properties.name === featureB); 28 | // https://stackoverflow.com/questions/43645172/geojson-multipolygon-with-multiple-holes 29 | featurea.geometry.coordinates.push(featureb.geometry.coordinates[0]); 30 | 31 | fs.writeFileSync("cut_" + jsonFile, JSON.stringify(geojson)); 32 | }; 33 | 34 | /** 35 | * Automic operation, both geojson file should have only one feature 36 | */ 37 | var cutAHoleInGeojsonByOther = (jsonFile, jsonFile2) => { 38 | data = fs.readFileSync(jsonFile, 'utf8'); 39 | 40 | var geojson = JSON.parse(data); 41 | 42 | data2 = fs.readFileSync(jsonFile2, 'utf8'); 43 | 44 | var second = JSON.parse(data2); 45 | // https://stackoverflow.com/questions/43645172/geojson-multipolygon-with-multiple-holes 46 | 47 | geojson.features[0].geometry.coordinates.push(second.features[0].geometry.coordinates[0]); 48 | 49 | fs.writeFileSync("cut_" + jsonFile, JSON.stringify(geojson)); 50 | }; 51 | 52 | var geoJsonToCompressed = (jsonFile, jsFile) => { 53 | 54 | data = fs.readFileSync(jsonFile, 'utf8'); 55 | 56 | var geojson = JSON.parse(data); 57 | 58 | if(!geojson.UTF8Encoding){ 59 | mapTool.compress(geojson); 60 | } 61 | fs.writeFileSync(jsFile, JSON.stringify(geojson)); 62 | 63 | }; 64 | 65 | var geoJsonToCompressedJs = (jsonFile, jsFile, registryName) => { 66 | 67 | data = fs.readFileSync(jsonFile, 'utf8'); 68 | 69 | var geojson = JSON.parse(data); 70 | 71 | if(!geojson.UTF8Encoding){ 72 | mapTool.compress(geojson); 73 | } 74 | fs.writeFileSync(jsFile, mapTool.makeJs(geojson, registryName)) 75 | 76 | }; 77 | 78 | var geoJsonListProperties = (jsonFile) => { 79 | fs.readFile(jsonFile, 'utf8', function (err, data) { 80 | if(err) throw err; 81 | 82 | var geojson = JSON.parse(data); 83 | 84 | geojson.features.forEach(function (feature){ 85 | console.log(JSON.stringify(feature.properties)); 86 | }); 87 | 88 | }); 89 | }; 90 | 91 | 92 | var geoJsonRenameAProperty = (jsonFile, oldProperty, newProperty) => { 93 | var data = fs.readFileSync(jsonFile, 'utf8') 94 | var geojson = JSON.parse(data); 95 | 96 | geojson.features.forEach(function (feature){ 97 | if(feature.properties[oldProperty]){ 98 | feature.properties[newProperty] = feature.properties[oldProperty]; 99 | delete feature.properties[oldProperty]; 100 | } 101 | }); 102 | 103 | fs.rename(jsonFile, jsonFile + '.backup', function(err){ 104 | if(err)throw err; 105 | fs.writeFileSync(jsonFile, JSON.stringify(geojson)); 106 | }); 107 | }; 108 | 109 | 110 | var geoJsonMergeTwoPropertiesAsOne = (jsonFile, propertyA, propertyB, newProperty) => { 111 | var data = fs.readFileSync(jsonFile, 'utf8') 112 | var geojson = JSON.parse(data); 113 | 114 | geojson.features.forEach(function (feature){ 115 | feature.properties[newProperty] = feature.properties[propertyA] + ' ' + feature.properties[propertyB]; 116 | if(feature.properties[propertyA]){ 117 | delete feature.properties[propertyA]; 118 | } 119 | if(feature.properties[propertyB]){ 120 | delete feature.properties[propertyB]; 121 | } 122 | }); 123 | 124 | fs.rename(jsonFile, jsonFile + '.backup', function(err){ 125 | if(err)throw err; 126 | fs.writeFileSync(jsonFile, JSON.stringify(geojson)); 127 | }); 128 | }; 129 | 130 | function jsToGeoJson(jsFile, outputGeoJsonFile){ 131 | data = fs.readFileSync(jsFile, 'utf8'); 132 | const regx = /registerMap\([\"\'].*?[\"\']\,/; 133 | const suffix = ");}));"; 134 | var tokens = data.split(regx); 135 | var geojson; 136 | if(tokens.length !== 2){ 137 | try{ 138 | geojson = JSON.parse(data); 139 | geojson = parser.decode(geojson); 140 | }catch(e){ 141 | console.log(tokens.length); 142 | console.log(e); 143 | throw new Error('Invalid js file.') 144 | } 145 | }else{ 146 | const heading = tokens[0]; 147 | var jsContent = tokens[1]; 148 | if(heading.indexOf('!function(') !== -1){ 149 | const endregx = /\)\:/; 150 | var subtokens = jsContent.split(endregx); 151 | jsContent = subtokens[0]; 152 | }else { 153 | if(heading.startsWith('(function')){ 154 | const endregx = /\)\;/; 155 | var subtokens = jsContent.split(endregx); 156 | jsContent = subtokens[0]; 157 | }else{ 158 | throw new Error('Cannot handle js file'); 159 | } 160 | } 161 | 162 | eval('var encodedGeoJson=' + jsContent+';'); 163 | geojson = parser.decode(encodedGeoJson) 164 | } 165 | fs.writeFileSync(outputGeoJsonFile, JSON.stringify(geojson)); 166 | } 167 | 168 | function merge(geojson, geojsonToBeMerged){ 169 | const data = fs.readFileSync(geojson, 'utf8'); 170 | const data2 = fs.readFileSync(geojsonToBeMerged, 'utf8'); 171 | var parent = JSON.parse(data); 172 | var child = JSON.parse(data2); 173 | 174 | child.features.forEach(function(feature){ 175 | parent.features = parent.features.filter((featurex)=>{ 176 | return featurex.properties.name!==feature.properties.name; 177 | }); 178 | parent.features.push(feature); 179 | }); 180 | fs.writeFileSync('merged_'+path.basename(geojson), JSON.stringify(parent)); 181 | } 182 | 183 | //geojson对象 184 | function Geojson() { 185 | this.type = "FeatureCollection"; 186 | this.features =[]; 187 | } 188 | 189 | 190 | function transform(geojson, geojson4echarts, mapName){ 191 | fs.readFile(geojson, 'utf8', function (err, data) { 192 | if(err)throw err; 193 | var shaper = JSON.parse(data); 194 | var echartsJson = new Geojson(); 195 | echartsJson.features = [ 196 | { 197 | "type": "Feature", 198 | "properties": { 199 | "name": mapName 200 | }, 201 | "geometry": shaper.geometries[0] 202 | } 203 | ]; 204 | 205 | fs.writeFileSync(geojson4echarts, JSON.stringify(echartsJson)); 206 | }) 207 | } 208 | 209 | function splitAllFeaturesAsGeojson(geojsonFile, folder) { 210 | const data = fs.readFileSync(geojsonFile); 211 | const geojson = JSON.parse(data); 212 | const flag = geojson.UTF8Encoding; 213 | 214 | geojson.features.forEach(function(feature){ 215 | const subGeo = new Geojson(); 216 | subGeo.features = [feature]; 217 | var targetFile = feature.properties.name + '.geojson'; 218 | if(flag){ 219 | subGeo.UTF8Encoding = flag; 220 | } 221 | if (folder){ 222 | targetFile = path.join(folder, targetFile); 223 | } 224 | fs.writeFileSync(targetFile, JSON.stringify(subGeo)); 225 | }) 226 | } 227 | 228 | function splitAllFeaturesAsJs(geojsonFile, folder) { 229 | const data = fs.readFileSync(geojsonFile); 230 | const geojson = JSON.parse(data); 231 | if(!geojson.UTF8Encoding){ 232 | mapTool.compress(geojson); 233 | } 234 | 235 | var names = []; 236 | 237 | geojson.features.forEach(function(feature){ 238 | const subGeo = new Geojson(); 239 | subGeo.features = [feature]; 240 | subGeo.UTF8Encoding = true; 241 | var name = feature.properties.name; 242 | const py_name = getPinyin(name); 243 | var targetFile = py_name + '.js'; 244 | if(folder){ 245 | targetFile = path.join(folder, targetFile); 246 | } 247 | names.push([name, targetFile]); 248 | fs.writeFileSync(targetFile, mapTool.makeJs(subGeo, name)); 249 | }); 250 | return names; 251 | } 252 | 253 | function decompressGeojson(geojsonfile, outputGeoJsonFile){ 254 | const data = fs.readFileSync(geojsonfile, 'utf8'); 255 | const geojson = JSON.parse(data); 256 | const decoded = parser.decode(geojson); 257 | fs.writeFileSync(outputGeoJsonFile, JSON.stringify(decoded)) 258 | } 259 | 260 | 261 | function getPinyin(Chinese_words){ 262 | const py = pinyin(Chinese_words, { 263 | style: pinyin.STYLE_TONE2 264 | }); 265 | return py.join('_'); 266 | } 267 | 268 | module.exports = { 269 | compress: geoJsonToCompressed, 270 | inspect: geoJsonListProperties, 271 | rename: geoJsonRenameAProperty, 272 | mergeProperty: geoJsonMergeTwoPropertiesAsOne, 273 | merge: merge, 274 | decompress: jsToGeoJson, 275 | decode: decompressGeojson, 276 | makeJs: geoJsonToCompressedJs, 277 | remove: removeAFeature, 278 | cut: cutAHoleInFeatureAWithFB, 279 | cutByFile: cutAHoleInGeojsonByOther, 280 | transform: transform, 281 | splitAsGeojson: splitAllFeaturesAsGeojson, 282 | splitAsJs: splitAllFeaturesAsJs 283 | } 284 | --------------------------------------------------------------------------------