我有这个图像: 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);    

}

但是,我无法对这些值实施Mercator投影。这些地块是合理准确的,但它们还不够好,该投影将解决。

我不知道该怎么做。我发现的所有例子都在解释如何为整个世界做到这一点。 这个 是解释如何实施投影的示例的好资源,但我无法使其正常工作。

另一个资源是 英国的极端点 我在英国各地获得边界框的纬度和经度值。他们也在这里:

northLat = 58.666667; 
northLong = -3.366667; 
eastLat = 52.481167; 
eastLong = 1.762833; 
southLat = 49.95;
southLong = -5.2; 
westLat = 54.45;
westLong = -8.166667;

如果有人可以帮助我,我将非常感谢!

谢谢

有帮助吗?

解决方案

我认为值得记住的是,并非所有扁平地图都是默卡托的预测。在不特别了解该地图的情况下,很难确定。您可能会发现世界上大部分地图更可能是 类型投影,地图上关注的区域比全局墨摩托车投影所在。当您远离赤道时,这一点尤其重要(英国足够远,至关重要)。

您可能可以使用您尝试的计算得出“足够近的”,但是为了最佳准确性,您可能需要使用具有明确定义的投影的地图,或者创建自己的地图。

其他提示

我写了一个函数,可以正是您想要的。我知道这有点晚了,但是也许还有其他一些人感兴趣。

您需要一张墨托投影的地图,您需要知道地图的LAT / LON位置。从 Tilemill 这是一个免费的软件 MAPBOX!

我正在使用此脚本,并用一些Google地球位置对其进行了测试。它在像素级别上工作完美。实际上,我没有在不同或更大的地图上测试它。希望它能帮助您!

拉斐尔;)

<?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];

?>

这是我使用Tilemill创建的图像,在此示例中使用了: map image

除了拉斐尔·威奇曼(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);
}

我已经将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};
}

这是另一个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
}

我知道这个问题是在不久前问的,但是ProJ4JS库是在JavaScript中不同地图投影之间转换的理想选择。

英国地图倾向于使用OSGB的国家电网,该网格基于横向墨摩托的投影。 IE。就像传统的墨托一样,但满90度,使“赤道”成为子午线。

@xarinko Actionscript摘要在JavaScript中(带有一些测试值)

var mapWidth = 1500;
var mapHeight = 1577;

var mapLonLeft = 9.8;
var mapLonRight = 10.2;
var mapLonDelta = mapLonRight - mapLonLeft;

var mapLatBottom = 53.45;
var mapLatBottomRadian = mapLatBottom * Math.PI / 180;



function convertPixelToGeo(tx, ty)
{   
    /* 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 = mapWidth / mapLonDelta * 360/(2 * Math.PI);     
    var mapOffsetY = ( worldMapRadius / 2 * Math.log( (1 + Math.sin(mapLatBottomRadian) ) / (1 - Math.sin(mapLatBottomRadian))  ));
    var equatorY = mapHeight + mapOffsetY;   
    var a = (equatorY-ty)/worldMapRadius;

    var lat = 180/Math.PI * (2 * Math.atan(Math.exp(a)) - Math.PI/2);
    var long = mapLonLeft+tx/mapWidth*mapLonDelta;
    return [lat,long];
}

convertPixelToGeo(241,444)

如果您想避免使用proj4js固有的LAT/LNG预测的某些更混乱的方面,则可以使用D3,它可以提供许多烘焙的投影,并呈现出精美的渲染。这是一个 交互式示例 方位角预测的几种口味。我更喜欢Albers使用美国地图。

如果D3不是最终用户选项 - 例如,您需要支持IE 7/8-您可以在D3中渲染,然后从D3生成的生成的SVG文件中获取XY坐标。然后,您可以在拉斐尔(Raphael)中渲染那些XY坐标。

此功能对我来说非常有用,因为我想根据我要绘制的地图来定义Mapheight。我正在生成PDF地图。我需要做的就是传递地图的最大LAT,Min LON,它将地图的像素大小返回[高度,宽度]。

converteotopixel(最大值,最大值)

在设置$ y的最后一步中的一个注释,如果您的坐标系“ xy”从底部/左开始,请勿从mapheight中减去计算,就像使用PDFS一样,这将倒转地图。

$y =  (($worldMapWidth / 2 * log((1 + sin($lat)) / (1 - sin($lat)))) - $mapOffsetY);

C#实施:

private Point ConvertGeoToPixel(
    double latitude, double longitude, // The coordinate to translate
    int imageWidth, int imageHeight, // The dimensions of the target space (in pixels)
    double mapLonLeft, double mapLonRight, double mapLatBottom // The bounds of the target space (in geo coordinates)
) {
    double mapLatBottomRad = mapLatBottom * Math.PI / 180;
    double latitudeRad = latitude * Math.PI / 180;

    double mapLonDelta = mapLonRight - mapLonLeft;
    double worldMapWidth = (imageWidth / mapLonDelta * 360) / (2 * Math.PI);
    double mapOffsetY = worldMapWidth / 2 * Math.Log((1 + Math.Sin(mapLatBottomRad)) / (1 - Math.Sin(mapLatBottomRad)));

    double x = (longitude - mapLonLeft) * (imageWidth / mapLonDelta);
    double y = imageHeight - ((worldMapWidth / 2 * Math.Log((1 + Math.Sin(latitudeRad)) / (1 - Math.Sin(latitudeRad)))) - mapOffsetY);

    return new Point()
    {
        X = Convert.ToInt32(x),
        Y = Convert.ToInt32(y)
    };
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top