根据geoJson判定经纬度是否在某个城市内

一、下载城市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;
	}

}

四、城市边界文件见附件

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值