Google地图偏移校正源码-使用本地数据库
Select messages from
# through # FAQ
[/[Print]\]

MGMaps -> 中文讨论

#1: Google地图偏移校正源码-使用本地数据库 Author: trisun PostPosted: Sun Oct 10, 2010 2:25 am
    —
代碼下載 http://download.csdn.net/source/2729939

地图偏移校正软件使用了本地数据库,数据库文件chinamapoffset.dat采用了二分法查询,你也可自行采用SQL数据库的方式。

可执行程序在Executable.rar,解压后执行 map.bat
这里给出完整地图纠偏代码 (包括像素偏移和经纬度偏移校正)

Code:



//--------------------------------- PACKAGE ------------------------------------
package com.pstreets.gisengine.demo;
//--------------------------------- IMPORTS ------------------------------------
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import com.mapdigit.gis.MapLayer;
import com.mapdigit.gis.geometry.GeoLatLng;
import com.mapdigit.gis.geometry.GeoPoint;
import java.io.File;
import java.io.RandomAccessFile;
import java.util.Hashtable;
//[------------------------------ MAIN CLASS ----------------------------------]

/**
 * The map in china has so-call offet, the laitude/longitude received by GPS device
 * is not actually mapped to the real position, it has "offset", this class
 * is used for amend such offset.
 */
public class LocalChinaMapOffset {
    RandomAccessFile mapOffsetDataFile=null;
    private static int RECORDCOUNT=9813676;
    private static int RECORDLENGTH=8;
    public void open(String filename) throws FileNotFoundException{
        mapOffsetDataFile=new RandomAccessFile(filename,"r");
    }
    public void open() throws FileNotFoundException, IOException{
        String path=(new java.io.File(".").getCanonicalPath())+File.separator;
        mapOffsetDataFile=new RandomAccessFile(path+"chinamapoffset.dat","r");
    }
    public void close() throws IOException{
        if(mapOffsetDataFile!=null){
            mapOffsetDataFile.close();
        }
    }
   
    /**
     * Get map offset at given location and level.
     * @param longitude longitude of WGS location.
     * @param latitude   latitude of WGS location.
     * @param mapLevel   map Level, 0-18.
     * @return offset in china.
     */
    public GeoPoint getOffset(double longitude, double latitude, int mapLevel) {
        if (mapLevel < 11) {
            return new GeoPoint(0, 0);
        }
        GeoPoint queryPoint = getQueryLocation(latitude, longitude);
        String key = queryPoint.x + "|" + queryPoint.y;
        GeoPoint cachedPoint = (GeoPoint) offsetCache.get(key);
        if (cachedPoint == null) {
            GeoPoint pt = getOffsetFromServer(queryPoint.x / 100.0, queryPoint.y / 100.0);
            offsetCache.put(key, pt);
            cachedPoint = pt;
        }
        return new GeoPoint((int)cachedPoint.x >> (18 - mapLevel),
                (int)cachedPoint.y>>(18 - mapLevel));
    }

    /**
     * Convert coordinates from WGS to Mars(China)
     * @param earth WGS lat/lng pair.
     * @return Mars' coordinates  lat/lng with deviation in China.
     */
    public GeoLatLng fromEarthToMars(GeoLatLng earth) {
        GeoPoint ptOffset = getOffset(earth.x, earth.y, 18);
        if (ptOffset.x != 0 || ptOffset.y != 0) {
            GeoPoint pt = MapLayer.fromLatLngToPixel(earth, 18);
            pt.x += ptOffset.x;
            pt.y += ptOffset.y;
            return MapLayer.fromPixelToLatLng(pt, 18);
        } else {
            return new GeoLatLng(earth);
        }
    }
   
    /**
     * Convert coordinates from  Mars(China) to WGS
     * @param mar   lat/lng with deviation in China.
     * @return WGS coordinates
     */
    public GeoLatLng fromMarsToEarth(GeoLatLng mar) {
        GeoPoint ptOffset = getOffset(mar.x, mar.y, 18);
        if (ptOffset.x != 0 || ptOffset.y != 0) {
            GeoPoint pt = MapLayer.fromLatLngToPixel(mar, 18);
            pt.x -= ptOffset.x;
            pt.y -= ptOffset.y;
            return MapLayer.fromPixelToLatLng(pt, 18);
        } else {
            return new GeoLatLng(mar);
        }
    }
   
    /**
     * internal cache.
     */
    private Hashtable offsetCache = new Hashtable(128);
   
   
    /**
     * normalized latitude and longitude.
     * @param latitude
     * @param longitude
     * @return
     */
    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 int readInt() throws IOException{
        int byte1=mapOffsetDataFile.readUnsignedByte();
        int byte2=mapOffsetDataFile.readUnsignedByte();
        return byte1+((int)byte2<<8);
    }
   
    /**
     * Get the offset from the sever.
     * @param longitude
     * @param latitude
     * @return
     */
    private GeoPoint getOffsetFromServer(double longitude, double latitude) {
                   int left = 0;
           try{
            int right = RECORDCOUNT;
            int lat,lng,offsetX,offsetY;
            lat=(int)latitude*100;
            lng=(int)longitude*100;
            long queryValue=lat+((long)lng<<16);
            while (left <= right)
            {
                int middle = (int)Math.floor((left + right) / 2.0);
                {
                    mapOffsetDataFile.seek(middle*RECORDLENGTH);
                    lng=readInt();
                        lat=readInt();
                        offsetX=readInt();
                        offsetY=readInt();
                    long middleValue =lat+((long)lng<<16);
                    if(queryValue==middleValue){
                        mapOffsetDataFile.seek(middle*RECORDLENGTH);
                        return new GeoPoint(offsetX, offsetY);
                    }
                    if (queryValue>middleValue)
                    {
                        left = middle + 1;
                    }
                    else
                    {
                        right = middle - 1;
                    }
                }
            }
        }catch(Exception e){}
       return new GeoPoint(0, 0);
    }
}

#2:  Author: golgo PostPosted: Fri Oct 22, 2010 1:47 am
    —
有人用过吗?给个意见啊

#3: Google地图偏移校正源码-使用本地数据库 Author: blackcd PostPosted: Sun Jun 19, 2011 3:01 am
    —
能不能再提供个下载地址,现在csdn好多东西都打不开了,不知道是服务器问题还是网站删了这些资源



MGMaps -> 中文讨论


output generated using printer-friendly topic mod. All times are GMT

Page 1 of 1

Powered by phpBB © 2001, 2005 phpBB Group