一、下载城市geoJson数据:
国家地理信息公共服务平台 天地图->服务中心->数据资源->行政区划可视化->市(下载数据)
二、maven依赖
https://mvnrepository.com/->jts-core
<dependency>
<groupId>org.locationtech.jts</groupId>
<artifactId>jts-core</artifactId>
<version>1.19.0</version>
</dependency>
三、代码
主要测试类:
// 创建Map用于存储Coordinate多边形对象
static Map<City, Coordinate[]> cityMap = new HashMap<>();
public static void main(String[] args) {
// 创建ObjectMapper对象
ObjectMapper objectMapper = new ObjectMapper();
// TODO 将这个类记录在博客里面
try {
// 读取.geojson文件并解析为JsonNode对象
File file = new File("C:\\Users\\Administrator\\Desktop\\city.geojson");
JsonNode rootNode = objectMapper.readTree(file);
// 获取FeatureCollection下的features数组
JsonNode featuresNode = rootNode.get("features");
// 遍历features数组
for (JsonNode featureNode : featuresNode) {
// 获取geometry字段
JsonNode geometryNode = featureNode.get("geometry");
// 获取类型字段
String type = geometryNode.get("type").asText();
// 获取坐标字段
JsonNode coordinatesNode = geometryNode.get("coordinates");
// 获取properties字段
JsonNode propertiesNode = featureNode.get("properties");
// 获取code字段
String code = propertiesNode.get("gb").asText();
String name = propertiesNode.get("name").asText();
City city = new City(code, name);
// 根据类型进行相应处理
if (type.equals("Polygon")) {
// 处理Polygon类型
Coordinate[] coordinates = parseCoordinates(coordinatesNode);
cityMap.put(city, coordinates);
} else if (type.equals("MultiPolygon")) {
// 处理MultiPolygon类型
for (JsonNode polygonNode : coordinatesNode) {
Coordinate[] coordinates = parseCoordinates(polygonNode);
cityMap.put(city, coordinates);
}
}
}
double longitude = 114.939284; // 经度
double latitude = 31.019928; // 纬度
City city = findContainingPolygon(longitude, latitude);
System.out.println("city_name: " + city.getCityName() + " ; city_code: " + city.getCityCode());
} catch (IOException e) {
e.printStackTrace();
}
}
public static Coordinate[] parseCoordinates(JsonNode coordinatesNode) {
if (!coordinatesNode.isArray()) {
return null; // 非法的 JSON 数组
}
List<Coordinate> coordinateList = new ArrayList<>();
double xF = coordinatesNode.get(0).get(0).get(0).asDouble();
double yF = coordinatesNode.get(0).get(0).get(1).asDouble();
Iterator<JsonNode> iterator = coordinatesNode.elements();
while (iterator.hasNext()) {
JsonNode coordinateNode = iterator.next();
if (coordinateNode.isArray() && coordinateNode.size() == 2) {
double x = coordinateNode.get(0).asDouble();
double y = coordinateNode.get(1).asDouble();
Coordinate coordinate = new Coordinate(x, y);
coordinateList.add(coordinate);
} else if (coordinateNode.isArray() && coordinateNode.size() > 2) {
Iterator<JsonNode> elements = coordinateNode.elements();
while (elements.hasNext()) {
JsonNode next = elements.next();
if (next.isArray() && next.size() == 2) {
double x = next.get(0).asDouble();
double y = next.get(1).asDouble();
Coordinate coordinate = new Coordinate(x, y);
coordinateList.add(coordinate);
}
}
} else {
return null; // 非法的坐标格式
}
}
// 一定要首尾相连
coordinateList.add(new Coordinate(xF, yF));
return coordinateList.toArray(new Coordinate[0]);
}
public static City findContainingPolygon(double longitude, double latitude) {
// 创建GeometryFactory
GeometryFactory geometryFactory = new GeometryFactory();
// 创建点坐标
Coordinate pointCoordinate = new Coordinate(longitude, latitude);
// 遍历多边形Map,查找包含点的多边形
for (Map.Entry<City, Coordinate[]> entry : cityMap.entrySet()) {
City city = entry.getKey();
Coordinate[] coordinates = entry.getValue();
try {
// 创建MultiPolygon对象
MultiPolygon multiPolygon = geometryFactory
.createMultiPolygon(new Polygon[] { new GeometryFactory().createPolygon(coordinates) });
// 使用PointLocator检查点是否在多边形内
PointLocator pointLocator = new PointLocator();
int location = pointLocator.locate(pointCoordinate, multiPolygon);
if (location != Location.EXTERIOR) {
return city;
}
} catch (Exception e) {
System.out.println("数据异常城市city_name:" + city.getCityName() + " ; city_code:" + city.getCityCode()
+ " ; 异常原因:" + e);
}
}
return new City(); // 未找到包含点的多边形
}
城市类(city):
public class City {
private String cityCode;
private String cityName;
public City() {
}
public City(String cityCode, String cityName) {
super();
this.cityCode = cityCode;
this.cityName = cityName;
}
public String getCityCode() {
return cityCode;
}
public void setCityCode(String cityCode) {
this.cityCode = cityCode;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
}
四、城市边界文件见附件