The Mobile Galaxy The New Mobile Era Has Come | Mobile – A Time To Remember

30Aug/114

中国地图偏移校正算法

该校正适用于 Google map China, Microsoft map china ,MapABC 等,因为这些地图构成方法是一样的。

需要offset.dat文件,该文件为0.01精度校正数据, 有需要者请联系作者, 报价: 5,000.00 RMB。

php算法

<?php
/*
   代码功能:利用0.01精度校正库文件修正中国地图经纬度偏移。
*/
header("Content-Type:text/html; charset=utf-8");
define('__dat_db__' , 'offset.dat' );// DAT数据文件
define('datmax' , 9813675 );// 数据条数-结束记录

// # offset.php?lat=39.914914&lon=116.460633
$lon=$_GET['lon'];
$lat=$_GET['lat'];
$tmplon=intval($lon * 100);
$tmplat=intval($lat * 100);
//经度到像素X值
function lngToPixel($lng,$zoom) {
return ($lng+180)*(256<<$zoom)/360;
}
//像素X到经度
function pixelToLng($pixelX,$zoom){
return $pixelX*360/(256<<$zoom)-180;
}
//纬度到像素Y
function latToPixel($lat, $zoom) {
$siny = sin($lat * pi() / 180);
$y=log((1+$siny)/(1-$siny));
return (128<<$zoom)*(1-$y/(2*pi()));
}
//像素Y到纬度
function pixelToLat($pixelY, $zoom) {
$y = 2*pi()*(1-$pixelY /(128 << $zoom));
$z = pow(M_E, $y);
$siny = ($z -1)/($z +1);
return asin($siny) * 180/pi();
}

function xy_fk( $number ){
        $fp = fopen(__dat_db__,"rb"); //■1■.将 r 改为 rb
        $myxy=$number;//#"112262582";
        $left = 0;//开始记录
        $right = datmax;//结束记录

        //采用用二分法来查找查数据
        while($left <= $right){
            $recordCount =(floor(($left+$right)/2))*8; //取半
            //echo "运算:left=".$left." right=".$right." midde=".$recordCount."<br />";
            @fseek ( $fp, $recordCount , SEEK_SET ); //设置游标
            $c = fread($fp,8); //读8字节
            $lon = unpack('s',substr($c,0,2));
            $lat = unpack('s',substr($c,2,2));
            $x = unpack('s',substr($c,4,2));
            $y = unpack('s',substr($c,6,2));
            $jwd=$lon[1].$lat[1];
            //echo "找到的经纬度:".$jwd;
            if ($jwd==$myxy){
               fclose($fp);
               return $x[1]."|".$y[1];
               break;
            }else if($jwd<$myxy){
               //echo " > ".$myxy."<br />";
               $left=($recordCount/8) +1;
            }else if($jwd>$myxy){
               //echo " < ".$myxy."<br />";
               $right=($recordCount/8) -1;
            }

        }
        fclose($fp);
}

$offset =xy_fk($tmplon.$tmplat);
$off=explode('|',$offset);
$lngPixel=lngToPixel($lon,18)+$off[0];
$latPixel=latToPixel($lat,18)+$off[1];

echo pixelToLat($latPixel,18).",".pixelToLng($lngPixel,18);

?>

c#算法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;   

namespace MapDigit.GIS
{
    public class GeoLatLng
    {   

        public GeoLatLng(double latitude, double longitude)
        {
            this.latitude = latitude;
            this.longitude = longitude;
        }
        public double latitude;
        public double longitude;
    }   

    public class GeoPoint
    {
        public GeoPoint(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
        public int x;
        public int y;
    }   

    public class OffsetInChina
    {
        //用于从GPS坐标转换为偏移后坐标
        public static GeoLatLng fromEarthToMars(GeoLatLng earth)
        {
            GeoPoint ptOffset = getOffset(earth.latitude, earth.longitude);
            if (ptOffset.x != 0 || ptOffset.y != 0)
            {
                int pixelX, pixelY;
                TileSystem.LatLongToPixelXY(earth.latitude, earth.longitude, 18, out pixelX, out pixelY);
                GeoPoint pt = new GeoPoint(pixelX, pixelY);
                pt.x += ptOffset.x;
                pt.y += ptOffset.y;
                double latitude, longitude;
                TileSystem.PixelXYToLatLong(pt.x, pt.y, 18, out latitude, out longitude);
                return new GeoLatLng(latitude, longitude);   

            }
            else
            {
                return new GeoLatLng(earth.latitude, earth.longitude);
            }   

        }   

        //用于将偏移后坐标转成真实的坐标
        public static GeoLatLng fromMarToEarth(GeoLatLng mars)
        {
            GeoPoint ptOffset = getOffset(mars.latitude, mars.longitude);
            if (ptOffset.x != 0 || ptOffset.y != 0)
            {
                int pixelX, pixelY;
                TileSystem.LatLongToPixelXY(mars.latitude, mars.longitude, 18, out pixelX, out pixelY);
                GeoPoint pt = new GeoPoint(pixelX, pixelY);
                pt.x -= ptOffset.x;
                pt.y -= ptOffset.y;
                double latitude, longitude;
                TileSystem.PixelXYToLatLong(pt.x, pt.y, 18, out latitude, out longitude);
                return new GeoLatLng(latitude, longitude);   

            }
            else
            {
                return new GeoLatLng(mars.latitude, mars.longitude);
            }
        }   

        //这个函数用于将需要查询的经纬度转成最近的0.01分度值,无插值
        //也可以自行实现插值
        private static GeoPoint getQueryLocation(double latitude, double longitude)
        {
            int lat = (int)(latitude * 100);
            int lng = (int)(longitude * 100);
            double lat1 = ((int)(latitude * 1000 + 0.499999)) / 10.0;
            double lng1 = ((int)(longitude * 1000 + 0.499999)) / 10.0;
            for (double x = longitude; x < longitude + 1; x += 0.5)
            {
                for (double y = latitude; x < latitude + 1; y += 0.5)
                {
                    if (x <= lng1 && lng1 < (x + 0.5) && lat1 >= y && lat1 < (y + 0.5))
                    {
                        return new GeoPoint((int)(x + 0.5), (int)(y + 0.5));
                    }
                }
            }
            return new GeoPoint(lng, lat);
        }   

        private static GeoPoint getOffset(double longitude, double latitude)
        {
            //这个函数用于返回查询结果,就是从校正数据中返回18级时x,y方偏移
            //可以自行实现
            return null;
        }   

    }
}
Share
Tagged as: , Leave a comment
Comments (4) Trackbacks (0)
  1. 需要offset.dat文件。主要是个人研究使用。
    谢谢

  2. Hello, can I a offset. Dat, thank you…


Leave a comment


*

No trackbacks yet.