java实现离线正反向地理编码代码
时间: 2023-11-13 19:19:31 浏览: 42
Java实现离线正反向地理编码需要用到第三方库,比如Geocoder、Geotools、OSM Nominatim等。以下是一个使用Geotools实现离线正向地理编码的示例代码:
```java
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.feature.simple.SimpleFeatureImpl;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.geometry.coordinate.Position;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
public class GeoCoder {
private ShapefileDataStore dataStore;
private SimpleFeatureType featureType;
private MathTransform transform;
private Map<Long, String> id2Name;
public GeoCoder(File shapefile) throws IOException {
dataStore = new ShapefileDataStore(shapefile.toURL());
featureType = dataStore.getSchema();
CoordinateReferenceSystem sourceCRS = featureType.getCoordinateReferenceSystem();
CoordinateReferenceSystem targetCRS = org.geotools.referencing.crs.DefaultGeographicCRS.WGS84;
transform = org.geotools.referencing.CRS.findMathTransform(sourceCRS, targetCRS, true);
id2Name = new HashMap<>();
SimpleFeatureIterator iterator = dataStore.getFeatureSource().getFeatures().features();
while (iterator.hasNext()) {
SimpleFeature feature = iterator.next();
long id = (Long) feature.getAttribute("ID");
String name = (String) feature.getAttribute("NAME");
id2Name.put(id, name);
}
iterator.close();
}
public String getAddress(double lat, double lon) throws IOException, TransformException {
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
Point point = geometryFactory.createPoint(new Coordinate(lon, lat));
Geometry targetGeometry = null;
try {
targetGeometry = JTS.transform(point, transform);
} catch (TransformException e) {
e.printStackTrace();
}
if (targetGeometry != null) {
String wktPoint = targetGeometry.toText();
String[] coords = wktPoint.replace("POINT (", "").replace(")", "").split(" ");
double x = Double.parseDouble(coords[0]);
double y = Double.parseDouble(coords[1]);
Geometry searchGeometry = geometryFactory.createPoint(new Coordinate(x, y));
try {
SimpleFeatureIterator iterator = dataStore.getFeatureSource().getFeatures().features();
while (iterator.hasNext()) {
SimpleFeature feature = iterator.next();
Geometry geometry = (Geometry) feature.getDefaultGeometry();
if (searchGeometry.intersects(geometry)) {
long id = (Long) feature.getAttribute("ID");
String name = id2Name.get(id);
return name;
}
}
iterator.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
```
示例代码使用了一个Shapefile作为地理编码数据源,通过读取Shapefile的属性表生成一个id到名称的映射表,并且可以通过给定的经纬度坐标返回对应的名称。