google卫星地图地图矫正

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

引路蜂地图开发包提供Java ME, Blackberry, Android, Windows Mobile iphone 等平台开发包,非常适合开发基于地图的移动应用。

这里给出完整地图纠偏代码 (包括像素偏移和经纬度偏移校正)

view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
//------------------------------------------------------------------------------
// COPYRIGHT 2010 GUIDEBEE
// ALL RIGHTS RESERVED.
// GUIDEBEE CONFIDENTIAL PROPRIETARY
///////////////////////////////////// REVISIONS ////////////////////////////////
// Date Name Tracking # Description
// --------- ------------------- ---------- --------------------------
// 19FEB2010 James Shen Code review
////////////////////////////////////////////////////////////////////////////////
//--------------------------------- 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 ----------------------------------]
////////////////////////////////////////////////////////////////////////////////
//--------------------------------- REVISIONS ----------------------------------
// Date Name Tracking # Description
// -------- ------------------- ------------- --------------------------
// 19FEB2010 James Shen Code review
////////////////////////////////////////////////////////////////////////////////
/**
* 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.
* <P>
* <hr>
* <hr><b>&copy; Copyright 2010 Guidebee Pty Ltd. All Rights Reserved.</b>
* @version 2.00, 19/02/10
* @author Guidebee Pty Ltd.
*/
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();
}
}
////////////////////////////////////////////////////////////////////////////
//--------------------------------- REVISIONS ------------------------------
// Date Name Tracking # Description
// --------- ------------------- ------------- ----------------------
// 19FEB2010 James Shen Code review
////////////////////////////////////////////////////////////////////////////
/**
* 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));
}
////////////////////////////////////////////////////////////////////////////
//--------------------------------- REVISIONS ------------------------------
// Date Name Tracking # Description
// --------- ------------------- ------------- ----------------------
// 19FEB2010 James Shen Code review
////////////////////////////////////////////////////////////////////////////
/**
* 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);
}
}
////////////////////////////////////////////////////////////////////////////
//--------------------------------- REVISIONS ------------------------------
// Date Name Tracking # Description
// --------- ------------------- ------------- ----------------------
// 19FEB2010 James Shen Code review
////////////////////////////////////////////////////////////////////////////
/**
* 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);

////////////////////////////////////////////////////////////////////////////
//--------------------------------- REVISIONS ------------------------------
// Date Name Tracking # Description
// --------- ------------------- ------------- ----------------------
// 19FEB2010 James Shen Code review
////////////////////////////////////////////////////////////////////////////
/**
* 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);
}
////////////////////////////////////////////////////////////////////////////
//--------------------------------- REVISIONS ------------------------------
// Date Name Tracking # Description
// --------- ------------------- ------------- ----------------------
// 19FEB2010 James Shen Code review
////////////////////////////////////////////////////////////////////////////
/**
* 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);
}
}
有偿提供矫正方式:caoxiancc@live.cn
原文地址:https://www.cnblogs.com/sharpmap/p/2088553.html