从数组中find国家坐标

我正在写一个小应用程序。 我有以下数据

{ "feat": [ { "type": "Feature", "id": "AFG", "properties": { "name": "Afghanistan" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 61.210817, 35.650072 ], [ 64.546479, 36.312073 ], [ 64.746105, 37.111818 ], [ 65.588948, 37.305217 ], [ 65.745631, 37.661164 ], [ 66.217385, 37.39379 ], [ 66.518607, 37.362784 ], [ 67.075782, 37.356144 ], [ 67.83, 37.144994 ], [ 68.135562, 37.023115 ], [ 68.859446, 37.344336 ], [ 69.196273, 37.151144 ], [ 69.518785, 37.608997 ], [ 70.116578, 37.588223 ], [ 70.270574, 37.735165 ], [ 71.262348, 36.074388 ], [ 71.498768, 35.650563 ], [ 71.613076, 35.153203 ], [ 71.115019, 34.733126 ], [ 71.156773, 34.348911 ], [ 70.881803, 33.988856 ], [ 69.930543, 34.02012 ], [ 70.323594, 33.358533 ], [ 69.687147, 33.105499 ], [ 69.262522, 32.501944 ], [ 69.317764, 31.901412 ], [ 68.926677, 31.620189 ], [ 68.556932, 31.71331 ], [ 67.792689, 31.58293 ], [ 60.52843, 33.676446 ], [ 60.803193, 34.404102 ], [ 61.210817, 35.650072 ] ] ] } }, { "type": "Feature", "id": "AGO", "properties": { "name": "Angola" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 16.326528, -5.87747 ], [ 16.57318, -6.622645 ], [ 16.860191, -7.222298 ], [ 17.089996, -7.545689 ], [ 17.47297, -8.068551 ], [ 21.801801, -8.908707 ], [ 21.875182, -9.523708 ], [ 22.208753, -9.894796 ], [ 22.155268, -11.084801 ], [ 22.402798, -10.993075 ], [ 22.837345, -11.017622 ], [ 23.456791, -10.867863 ], [ 23.912215, -10.926826 ], [ 24.017894, -11.237298 ], [ 23.904154, -11.722282 ], [ 24.079905, -12.191297 ], [ 23.930922, -12.565848 ], [ 24.016137, -12.911046 ], [ 21.933886, -12.898437 ], [ 21.887843, -16.08031 ], [ 22.562478, -16.898451 ], [ 23.215048, -17.523116 ], [ 21.377176, -17.930636 ], [ 18.956187, -17.789095 ], [ 18.263309, -17.309951 ], [ 12.175619, -14.449144 ], [ 12.500095, -13.5477 ], [ 12.738479, -13.137906 ], [ 13.312914, -12.48363 ], [ 13.633721, -12.038645 ], [ 13.738728, -11.297863 ], [ 13.686379, -10.731076 ], [ 13.387328, -10.373578 ], [ 13.120988, -9.766897 ], [ 12.87537, -9.166934 ], [ 13.375597, -5.864241 ], [ 16.326528, -5.87747 ] ] ], [ [ [ 12.436688, -5.684304 ], [ 12.182337, -5.789931 ] ] ] ] } }, { "type": "Feature", "id": "ALB", "properties": { "name": "Albania" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 20.590247, 41.855404 ], [ 19.406082, 40.250773 ], [ 19.319059, 40.72723 ], [ 19.40355, 41.409566 ], [ 19.540027, 41.719986 ], [ 19.371769, 41.877548 ], [ 19.304486, 42.195745 ], [ 19.738051, 42.688247 ], [ 19.801613, 42.500093 ], [ 20.0707, 42.58863 ], [ 20.283755, 42.32026 ], [ 20.52295, 42.21787 ], [ 20.590247, 41.855404 ] ] ] } } ] } 

会发生什么事是用户将提供latitudelongitude 。 然后我需要find这些值是否存在于上面的数据集中。 如果是,那么返回该国家。

问题是上面的数据集坐标数组是不同的。 有时候是三维的,有时候是二维的。 我不知道如何find有效的解决scheme。

下面是我的一些代码,目前它提示用户从经纬度和循环的数据。

 const rl = require('readline').createInterface(process.stdin, process.stdout); const coordinates = require('./data.json').feat; var prompts = ['Enter coordinates (lat, lon)'], counter = 0; // console.log(countries); rl.on('line', (line) => { if (!line) { console.log('Enter values.'); } let lat = line.split(' ')[0], lon = line.split(' ')[1]; console.log(lat, lon); coordinates.forEach((data, index) => { console.log(data.geometry.coordinates[index]); data.geometry.coordinates.forEach((geo, i) => { // console.log(geo[i]); }); }); get(); }).on('close', () => { }); function get() { rl.setPrompt(prompts[counter] + ': '); rl.prompt(); } get(); 

在上面的数据集中寻找经度和纬度的帮助?

您可以通过检查type属性来检测多边形的数量。 如果是MultiPolygon ,则会有一个嵌套级别。

这里有一些函数可以用来确定一个点是否在一个多边形中。 片段的其余部分(下半部分)允许testinggetCountry函数:它执行地图绘制,鼠标移动处理以及显示鼠标移过的国家。 但其本质在于三大function。

这是简单的JS,基于本文中提供的绕线algorithm,但您可能需要考虑使用库,而不是像d3.js。

 function isLeft(p0, p1, p2) { return ( (p1[0] - p0[0]) * (p2[1] - p0[1]) - (p2[0] - p0[0]) * (p1[1] - p0[1]) ); } function inPoly(p, coord) { var winding = 0; // loop through all edges of the polygon for (var i=0; i<coord.length-1; i++) { if (coord[i][1] <= p[1]) { if (coord[i+1][1] > p[1]) // an upward crossing if (isLeft(coord[i], coord[i+1], p) > 0) // p left of edge ++winding; // have a valid up intersect } else { // start y > Py (no test needed) if (coord[i+1][1] <= p[1]) // a downward crossing if (isLeft(coord[i], coord[i+1], p) < 0) // p right of edge --winding; // have a valid down intersect } } return winding; } function getCountry(p, data) { // p: point represented by array with the two coordinates var country; return data.feat.some(function (obj) { country = obj; var polygons = obj.geometry.coordinates; if (obj.geometry.type !== 'MultiPolygon') polygons = [polygons]; return polygons.some(function (polygon) { return inPoly(p, polygon[0]); }); }) ? country : null; } // I/O for this interactive snippet function drawPolygon(ctx, coord, fillColor) { ctx.fillStyle = fillColor; ctx.beginPath(); coord.forEach(function (point, i) { if (i==0) { ctx.moveTo(point[0], point[1]); } else { ctx.lineTo(point[0], point[1]); } }); ctx.fill(); ctx.stroke(); // ctx.closePath(); } function drawCountry(ctx, selectedCountry, country) { var polygons = country.geometry.coordinates; var color = selectedCountry == country ? 'yellow' : 'grey'; if (country.geometry.type !== 'MultiPolygon') polygons = [polygons]; polygons.forEach(function (polygon) { drawPolygon(ctx, polygon[0], color); }); } function drawWorld(ctx, data, selectedCountry) { data.feat.forEach(drawCountry.bind(null, ctx, selectedCountry)); } // Define transformation so countries will be mapped to canvas area var scale = [3, -3]; var move = [-20, 130]; var canvas = document.querySelector('canvas'); var ctx = canvas.getContext("2d"); ctx.translate(...move); ctx.scale(...scale); ctx.lineWidth = 1/scale[0]; // Sample data var data = {"feat":[{"type":"Feature","id":"AFG","properties":{"name":"Afghanistan"},"geometry":{"type":"Polygon","coordinates":[[[61.210817,35.650072],[62.230651,35.270664],[62.984662,35.404041],[63.193538,35.857166],[63.982896,36.007957],[64.546479,36.312073],[64.746105,37.111818],[65.588948,37.305217],[65.745631,37.661164],[66.217385,37.39379],[66.518607,37.362784],[67.075782,37.356144],[67.83,37.144994],[68.135562,37.023115],[68.859446,37.344336],[69.196273,37.151144],[69.518785,37.608997],[70.116578,37.588223],[70.270574,37.735165],[70.376304,38.138396],[70.806821,38.486282],[71.348131,38.258905],[71.239404,37.953265],[71.541918,37.905774],[71.448693,37.065645],[71.844638,36.738171],[72.193041,36.948288],[72.63689,37.047558],[73.260056,37.495257],[73.948696,37.421566],[74.980002,37.41999],[75.158028,37.133031],[74.575893,37.020841],[74.067552,36.836176],[72.920025,36.720007],[71.846292,36.509942],[71.262348,36.074388],[71.498768,35.650563],[71.613076,35.153203],[71.115019,34.733126],[71.156773,34.348911],[70.881803,33.988856],[69.930543,34.02012],[70.323594,33.358533],[69.687147,33.105499],[69.262522,32.501944],[69.317764,31.901412],[68.926677,31.620189],[68.556932,31.71331],[67.792689,31.58293],[67.683394,31.303154],[66.938891,31.304911],[66.381458,30.738899],[66.346473,29.887943],[65.046862,29.472181],[64.350419,29.560031],[64.148002,29.340819],[63.550261,29.468331],[62.549857,29.318572],[60.874248,29.829239],[61.781222,30.73585],[61.699314,31.379506],[60.941945,31.548075],[60.863655,32.18292],[60.536078,32.981269],[60.9637,33.528832],[60.52843,33.676446],[60.803193,34.404102],[61.210817,35.650072]]]}},{"type":"Feature","id":"AGO","properties":{"name":"Angola"},"geometry":{"type":"MultiPolygon","coordinates":[[[[16.326528,-5.87747],[16.57318,-6.622645],[16.860191,-7.222298],[17.089996,-7.545689],[17.47297,-8.068551],[18.134222,-7.987678],[18.464176,-7.847014],[19.016752,-7.988246],[19.166613,-7.738184],[19.417502,-7.155429],[20.037723,-7.116361],[20.091622,-6.94309],[20.601823,-6.939318],[20.514748,-7.299606],[21.728111,-7.290872],[21.746456,-7.920085],[21.949131,-8.305901],[21.801801,-8.908707],[21.875182,-9.523708],[22.208753,-9.894796],[22.155268,-11.084801],[22.402798,-10.993075],[22.837345,-11.017622],[23.456791,-10.867863],[23.912215,-10.926826],[24.017894,-11.237298],[23.904154,-11.722282],[24.079905,-12.191297],[23.930922,-12.565848],[24.016137,-12.911046],[21.933886,-12.898437],[21.887843,-16.08031],[22.562478,-16.898451],[23.215048,-17.523116],[21.377176,-17.930636],[18.956187,-17.789095],[18.263309,-17.309951],[14.209707,-17.353101],[14.058501,-17.423381],[13.462362,-16.971212],[12.814081,-16.941343],[12.215461,-17.111668],[11.734199,-17.301889],[11.640096,-16.673142],[11.778537,-15.793816],[12.123581,-14.878316],[12.175619,-14.449144],[12.500095,-13.5477],[12.738479,-13.137906],[13.312914,-12.48363],[13.633721,-12.038645],[13.738728,-11.297863],[13.686379,-10.731076],[13.387328,-10.373578],[13.120988,-9.766897],[12.87537,-9.166934],[12.929061,-8.959091],[13.236433,-8.562629],[12.93304,-7.596539],[12.728298,-6.927122],[12.227347,-6.294448],[12.322432,-6.100092],[12.735171,-5.965682],[13.024869,-5.984389],[13.375597,-5.864241],[16.326528,-5.87747]]],[[[12.436688,-5.684304],[12.182337,-5.789931],[11.914963,-5.037987],[12.318608,-4.60623],[12.62076,-4.438023],[12.995517,-4.781103],[12.631612,-4.991271],[12.468004,-5.248362],[12.436688,-5.684304]]]]}},{"type":"Feature","id":"ALB","properties":{"name":"Albania"},"geometry":{"type":"Polygon","coordinates":[[[20.590247,41.855404],[20.463175,41.515089],[20.605182,41.086226],[21.02004,40.842727],[20.99999,40.580004],[20.674997,40.435],[20.615,40.110007],[20.150016,39.624998],[19.98,39.694993],[19.960002,39.915006],[19.406082,40.250773],[19.319059,40.72723],[19.40355,41.409566],[19.540027,41.719986],[19.371769,41.877548],[19.304486,42.195745],[19.738051,42.688247],[19.801613,42.500093],[20.0707,42.58863],[20.283755,42.32026],[20.52295,42.21787],[20.590247,41.855404]]]}}]}; // Show map on canvas window.onload = drawWorld.bind(null, ctx, data, null); // Handle mouse move to mention the matching country canvas.onmousemove = function (e) { // Get mouse coordinates relative to canvas var x = e.pageX - this.offsetLeft; var y = e.pageY - this.offsetTop; // Perform the reverse of the canvas transformation x = (x - move[0]) / scale[0]; y = (y - move[1]) / scale[1]; // Get country that contains this point var country = getCountry([x, y], data); var countryName = country ? country.properties.name : 'no match'; // Output the result document.getElementById('country').textContent = countryName; // Highight country drawWorld(ctx, data, country) }; 
 canvas { border:1px solid; float: left } 
 <canvas width="250", height="200"></canvas> <div id="country">Hover mouse...</div> 

你的coordinates只是另一个嵌套的坐标数组,在多重对象的情况下,但结构是相同的,所以尝试这样的事情:

 var list = feat;//feat has the json response list.forEach(function(val, index) { var temp = val.geometry; var set = []; var type = temp.type.toLowerCase();//just for sake of simplicity var coords = []; if(type=='polygon') coords = temp.coordinates[0];//which is an array of long-lats else { var a = []; temp.coordinates.forEach(function(coord) { a.concat(coord[0]);//note that the 0th index of each array has the list of long-lats }) coords = a; } temp.coordinates = coords; }); 

每个对象的coordinates键现在应该有一个lat-long列表的一维数组。 我没有testing过这个代码,所以请检查一下。 您可以testing给定一对coordinates每个coordinates索引。 请注意,上面的代码只是简化了你的响应结构,并没有执行实际的search。