在JavaScript中查找多边形的中心点
我有一个来自谷歌地图的“地点”对象,它有一组坐标表示给定位置的边界框,比如伦敦。每一组坐标都有一个纬度和经度 我已经编写了下面的代码来查找中心点,但我不确定它是否确实生成了中心点。如果多边形有5个点而不是4个点怎么办?此外,能否以更高效的方式,以更少的操作来实现这一点在JavaScript中查找多边形的中心点,javascript,google-maps,math,geolocation,geometry,Javascript,Google Maps,Math,Geolocation,Geometry,我有一个来自谷歌地图的“地点”对象,它有一组坐标表示给定位置的边界框,比如伦敦。每一组坐标都有一个纬度和经度 我已经编写了下面的代码来查找中心点,但我不确定它是否确实生成了中心点。如果多边形有5个点而不是4个点怎么办?此外,能否以更高效的方式,以更少的操作来实现这一点 function average(array) { // Add together and then divide by the length return _.reduce(array, function (sum, n
function average(array) {
// Add together and then divide by the length
return _.reduce(array, function (sum, num) {
return sum + num;
}, 0) / array.length;
}
// I have a two-dimensional array that I want to get the average of
var coords = [
[ -1.2, 5.1 ],
[ -1.3, 5.2 ],
[ -1.8, 5.9 ],
[ -1.9, 5.8 ]
]
// So I get the first column
var lats = coords.map(function (coord) {
return coord[0];
})
// Then the second
var longs = coords.map(function (coord) {
return coord[1];
})
// And average each column out
console.log([average(lats), average(longs)])
.我意识到这并不是你想要的,但如果没有其他人回答,可能会有所帮助。这是一个PHP函数,我使用它为我的地图应用程序查找多边形的中心点。它应该很容易转换为javascript供您使用
function getCenter($coord_array){
$i = 0;
$center = $coord_array[0];
unset($coord_array[0]);
foreach($coord_array as $key => $coord){
$plat = $coord[0];
$plng = $coord[1];
$clat = $center[0];
$clng = $center[1];
$mlat = ($plat + ($clat * $i)) / ($i + 1);
$mlng = ($plng + ($clng * $i)) / ($i + 1);
$center = array($mlat, $mlng);
$i++;
}
return array($mlat, $mlng);
}
请注意,多边形必须闭合,这意味着阵列中的第一个点和阵列中的最后一个点是相同的
将坐标字符串转换为所需数组的函数:
function coordStringToArray($coord_string)
{
$coord_array = explode("\n",$coord_string);
foreach($coord_array as $key => $coord){
$coord_array[$key] = explode(', ',$coord);
}
return $coord_array;
}
原始坐标字符串的示例:
42.390576, -71.074258
42.385822, -71.077091
42.382461, -71.079408
42.382018, -71.081468
42.380496, -71.080953
42.380433, -71.076576
42.373902, -71.073915
42.373078, -71.069967
42.369273, -71.064216
42.368892, -71.062328
42.369527, -71.056491
42.370288, -71.050741
42.371619, -71.047908
42.376185, -71.046278
42.383476, -71.045763
42.386139, -71.050483
42.386202, -71.057693
42.387597, -71.066534
42.390259, -71.072284
42.391210, -71.073658
这将以数组形式获取任何形状的中心点[centerX,centerY]:
var center = function (arr)
{
var minX, maxX, minY, maxY;
for (var i = 0; i < arr.length; i++)
{
minX = (arr[i][0] < minX || minX == null) ? arr[i][0] : minX;
maxX = (arr[i][0] > maxX || maxX == null) ? arr[i][0] : maxX;
minY = (arr[i][1] < minY || minY == null) ? arr[i][1] : minY;
maxY = (arr[i][1] > maxY || maxY == null) ? arr[i][1] : maxY;
}
return [(minX + maxX) / 2, (minY + maxY) / 2];
}
或者,如果您的浏览器支持ECMAScript 6,则可以使用和,如下所示:
var center = function (arr)
{
var x = arr.map (xy => xy[0]);
var y = arr.map (xy => xy[1]);
var cx = (Math.min (...x) + Math.max (...x)) / 2;
var cy = (Math.min (...y) + Math.max (...y)) / 2;
return [cx, cy];
}
要在Google Maps API v3(未测试)中获取多边形的边界(包含数据),请执行以下操作:
var-coords=[
[ -1.2, 5.1 ],
[ -1.3, 5.2 ],
[ -1.8, 5.9 ],
[ -1.9, 5.8 ]
];
var bounds=new google.maps.LatLngBounds();
对于(var i=0;i这应该得到任何
/*jslint sub:true,maxerr:50,缩进:4,浏览器:true*/
/*全局控制台*/
(功能(){
“严格使用”;
功能点(x,y){
这个.x=x;
这个。y=y;
}
功能区(点){
this.points=点| |[];
this.length=points.length;
}
Region.prototype.area=函数(){
var面积=0,
我
J
第1点,
第2点;
对于(i=0,j=this.length-1;i
在上,这里是我的es6解决方案,用于平均一组纬度和经度。
平均值不是精确的中心点,但在我的例子中它完成了工作
getLatLonCenterFromGeom = (coords) => {
const arrAvg = arr => arr.reduce((a,b) => a + b, 0) / arr.length;
const centerLat = arrAvg(coords.map(c=>c.latitude));
const centerLon = arrAvg(coords.map(c=>c.longitude));
if (isNaN(centerLat)|| isNaN(centerLon))
return null;
else return {latitude: centerLat, longitude:centerLon};
}
//纯JavaScript版本
函数getCenterPoint(polygonId){
var p=document.getElementById(polygonId).points;
//设置初始最小值和最大值
var minX=p[0].x,maxX=p[0].x,minY=p[0].y,maxY=p[0].y;
对于(var i=0;i maxX){maxX=p[i].x;}
如果(p[i].ymaxY){maxY=p[i].y;}
}
返回[(最大+最小)/2,(最大+最小)/2];
}
centerPoint=getCenterPoint(“MyPolygonId”);您是否使用?我建议先获取多边形的边界,然后使用边界的中心。@geocodezip我相信这就是我的“边界框”.我之所以接受这个答案,是因为它明确地回答了我的问题,尽管我在我的应用程序中使用了@razzak提供的Google Maps API答案。除非你找到一些信息表明它不是。
var coords = [
[ -1.2, 5.1 ],
[ -1.3, 5.2 ],
[ -1.8, 5.9 ],
[ -1.9, 5.8 ]
];
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i<coords.length; i++) {
bounds.extend(new google.maps.LatLng(coords[i][0], coords[i][1]));
}
var center = bounds.getCenter();
var latitude = center.lat(); // latitude=-1.5499999999999998
var longitude = center.lng(); // longitude=5.5
var coordinates = center.toUrlValue(); // coordinates=-1.55,5.5
/*jslint sub: true, maxerr: 50, indent: 4, browser: true */
/*global console */
(function () {
"use strict";
function Point(x, y) {
this.x = x;
this.y = y;
}
function Region(points) {
this.points = points || [];
this.length = points.length;
}
Region.prototype.area = function () {
var area = 0,
i,
j,
point1,
point2;
for (i = 0, j = this.length - 1; i < this.length; j=i,i++) {
point1 = this.points[i];
point2 = this.points[j];
area += point1.x * point2.y;
area -= point1.y * point2.x;
}
area /= 2;
return area;
};
Region.prototype.centroid = function () {
var x = 0,
y = 0,
i,
j,
f,
point1,
point2;
for (i = 0, j = this.length - 1; i < this.length; j=i,i++) {
point1 = this.points[i];
point2 = this.points[j];
f = point1.x * point2.y - point2.x * point1.y;
x += (point1.x + point2.x) * f;
y += (point1.y + point2.y) * f;
}
f = this.area() * 6;
return new Point(x / f, y / f);
};
var polygon = [
{"x": -1.2, "y": 5.1},
{"x": -1.3, "y": 5.2},
{"x": -1.8, "y": 5.9},
{"x": -1.9, "y": 5.8}
],
region = new Region(polygon);
console.log(region.centroid());
}());
getLatLonCenterFromGeom = (coords) => {
const arrAvg = arr => arr.reduce((a,b) => a + b, 0) / arr.length;
const centerLat = arrAvg(coords.map(c=>c.latitude));
const centerLon = arrAvg(coords.map(c=>c.longitude));
if (isNaN(centerLat)|| isNaN(centerLon))
return null;
else return {latitude: centerLat, longitude:centerLon};
}
//Pure JavaScript version
function getCenterPoint(polygonId){
var p=document.getElementById(polygonId).points;
//Set initial min and max values
var minX=p[0].x, maxX=p[0].x, minY=p[0].y, maxY=p[0].y;
for(var i=0;i<p.length; i++){
if(p[i].x < minX){minX=p[i].x;}
if(p[i].x > maxX){maxX=p[i].x;}
if(p[i].y < minY){minY=p[i].y;}
if(p[i].y > maxY){maxY=p[i].y;}
}
return [(maxX + minX)/2, (maxY + minY)/2];
}