bet*_*max 16 javascript projection geolocation processing.js proj4js
我有这张图片:http://imgur.com/99tSz.png.英国地图(不包括南爱尔兰).
我已经成功地获得了经度和经度,并通过获取英国最左边的经度和最右经度并使用它们来确定将点放在地图上的位置,将其绘制到此地图上.
这是代码(用于Processing.js但可以用作js或任何东西):
// Size of the map
int width = 538;
int height = 811;
// X and Y boundaries
float westLong = -8.166667;
float eastLong = 1.762833;
float northLat = 58.666667;
float southLat = 49.95;
void drawPoint(float latitude, float longitude){
fill(#000000);
x = width * ((westLong-longitude)/(westLong-eastLong));
y = (height * ((northLat-latitude)/(northLat-southLat)));
console.log(x + ", " + y);
ellipseMode(RADIUS);
ellipse(x, y, 2, 2);
}
Run Code Online (Sandbox Code Playgroud)
但是,我无法对这些值实施墨卡托投影.这些图很合理,但它们不够好,这个投影可以解决它.
我无法弄清楚该怎么做.我找到的所有例子都在解释如何为整个世界做这件事.这是一个很好的示例资源,解释了如何实现投影,但我无法让它工作.
另一个资源是英国的极端点,我获得了英国各地边界框的纬度和经度值.他们也在这里:
northLat = 58.666667;
northLong = -3.366667;
eastLat = 52.481167;
eastLong = 1.762833;
southLat = 49.95;
southLong = -5.2;
westLat = 54.45;
westLong = -8.166667;
Run Code Online (Sandbox Code Playgroud)
如果有人能帮助我,我会非常感激!
谢谢
Rap*_*ael 39
我写了一个函数,它完全符合您的要求.我知道这有点晚了,但也许还有其他人感兴趣.
你需要一张是墨卡托投影的地图,你需要知道地图的纬度/经度位置.您就可以从完善的配套经/纬度位置得到很大的定制墨卡托地图TileMill这是一个免费软件MapBox!
我正在使用这个脚本,并测试了一些谷歌地球位置.它在像素级别上工作得很好.实际上我没有在不同或更大的地图上测试这个.我希望它对你有所帮助!
拉斐尔;)
<?php
$mapWidth = 1500;
$mapHeight = 1577;
$mapLonLeft = 9.8;
$mapLonRight = 10.2;
$mapLonDelta = $mapLonRight - $mapLonLeft;
$mapLatBottom = 53.45;
$mapLatBottomDegree = $mapLatBottom * M_PI / 180;
function convertGeoToPixel($lat, $lon)
{
global $mapWidth, $mapHeight, $mapLonLeft, $mapLonDelta, $mapLatBottom, $mapLatBottomDegree;
$x = ($lon - $mapLonLeft) * ($mapWidth / $mapLonDelta);
$lat = $lat * M_PI / 180;
$worldMapWidth = (($mapWidth / $mapLonDelta) * 360) / (2 * M_PI);
$mapOffsetY = ($worldMapWidth / 2 * log((1 + sin($mapLatBottomDegree)) / (1 - sin($mapLatBottomDegree))));
$y = $mapHeight - (($worldMapWidth / 2 * log((1 + sin($lat)) / (1 - sin($lat)))) - $mapOffsetY);
return array($x, $y);
}
$position = convertGeoToPixel(53.7, 9.95);
echo "x: ".$position[0]." / ".$position[1];
?>
Run Code Online (Sandbox Code Playgroud)
这是我使用TileMill创建的图像,我在此示例中使用了该图像: 
小智 10
除了Raphael Wichmann发布的内容之外(顺便说一下,谢谢!),这里是反向函数,在actionscript中:
function convertPixelToGeo(tx:Number, ty:Number):Point
{
/* called worldMapWidth in Raphael's Code, but I think that's the radius since it's the map width or circumference divided by 2*PI */
var worldMapRadius:Number = mapWidth / mapLonDelta * 360/(2 * Math.PI);
var mapOffsetY:Number = ( worldMapRadius / 2 * Math.log( (1 + Math.sin(mapLatBottomRadian) ) / (1 - Math.sin(mapLatBottomRadian)) ));
var equatorY:Number = mapHeight + mapOffsetY;
var a:Number = (equatorY-ty)/worldMapRadius;
var lat:Number = 180/Math.PI * (2 * Math.atan(Math.exp(a)) - Math.PI/2);
var long:Number = mapLonLeft+tx/mapWidth*mapLonDelta;
return new Point(lat,long);
}
Run Code Online (Sandbox Code Playgroud)
我已经将Raphael提供的PHP代码转换为JavaScript并且可以确认它有效并且此代码可以自行运行.所有归功于拉斐尔.
/*
var mapWidth = 1500;
var mapHeight = 1577;
var mapLonLeft = 9.8;
var mapLonRight = 10.2;
var mapLonDelta = mapLonRight - mapLonLeft;
var mapLatBottom = 53.45;
var mapLatBottomDegree = mapLatBottom * Math.PI / 180;
*/
function convertGeoToPixel(latitude, longitude ,
mapWidth , // in pixels
mapHeight , // in pixels
mapLonLeft , // in degrees
mapLonDelta , // in degrees (mapLonRight - mapLonLeft);
mapLatBottom , // in degrees
mapLatBottomDegree) // in Radians
{
var x = (longitude - mapLonLeft) * (mapWidth / mapLonDelta);
latitude = latitude * Math.PI / 180;
var worldMapWidth = ((mapWidth / mapLonDelta) * 360) / (2 * Math.PI);
var mapOffsetY = (worldMapWidth / 2 * Math.log((1 + Math.sin(mapLatBottomDegree)) / (1 - Math.sin(mapLatBottomDegree))));
var y = mapHeight - ((worldMapWidth / 2 * Math.log((1 + Math.sin(latitude)) / (1 - Math.sin(latitude)))) - mapOffsetY);
return { "x": x , "y": y};
}
Run Code Online (Sandbox Code Playgroud)
I think it's worthwhile to keep in mind that not all flat maps are Mercator projections. Without knowing more about that map in particular, it's hard to be sure. You may find that most maps of a small area of the world are more likely to be a conical type projection, where the area of interest on the map is "flatter" than would be on a global Mercator projection. This is especially more important the further you get away from the equator (and the UK is far enough away for it to matter).
You may be able to get "close enough" using the calculations you're trying, but for best accuracy you may want to either use a map with a well-defined projection, or create your own map.
这是另一个Javascript实现。这是上述@Rob Willet解决方案的简化。不需要将计算值作为函数的参数,它只需要基本值并从中计算所有内容:
function convertGeoToPixel(latitude, longitude,
mapWidth, // in pixels
mapHeight, // in pixels
mapLngLeft, // in degrees. the longitude of the left side of the map (i.e. the longitude of whatever is depicted on the left-most part of the map image)
mapLngRight, // in degrees. the longitude of the right side of the map
mapLatBottom) // in degrees. the latitude of the bottom of the map
{
const mapLatBottomRad = mapLatBottom * Math.PI / 180
const latitudeRad = latitude * Math.PI / 180
const mapLngDelta = (mapLngRight - mapLngLeft)
const worldMapWidth = ((mapWidth / mapLngDelta) * 360) / (2 * Math.PI)
const mapOffsetY = (worldMapWidth / 2 * Math.log((1 + Math.sin(mapLatBottomRad)) / (1 - Math.sin(mapLatBottomRad))))
const x = (longitude - mapLngLeft) * (mapWidth / mapLngDelta)
const y = mapHeight - ((worldMapWidth / 2 * Math.log((1 + Math.sin(latitudeRad)) / (1 - Math.sin(latitudeRad)))) - mapOffsetY)
return {x, y} // the pixel x,y value of this point on the map image
}
Run Code Online (Sandbox Code Playgroud)