地图分块查询及计算点面关系

批量计算点和面的关系时,需要双循环进行遍历,当数据量较大时循环计算效率很低。最好时将地图分成等量的方格,每次只查询单个方格内的数据进行点和面的关系计算能极大的提高计算效率。


/**
 * 根据地图范围将地图等量分割成 N*N的方格
 * @author LuXiangQi
 *
 */
public class Bounds {
	/**
	 *  等分数量,即将地图分割成16*16块区域
	 */
	public static final int PARTS = 16;
	
	private double minX;
	private double maxX;
	private double minY;
	private double maxY;
	
	private Double dx;
	private Double dy;
	
	@Override
	public String toString() {
		DecimalFormat df = new DecimalFormat("#.000000000000000");
		return "Bounds [minX=" + df.format(minX) + ", maxX=" + df.format(maxX) + ", minY=" + df.format(minY)
				+ ", maxY=" + df.format(maxY) + "]"; 
	}
	
	public Bounds(double minX, double maxX, double minY, double maxY) {
		this.minX = minX;
		this.maxX = maxX;
		this.minY = minY;
		this.maxY = maxY;
		getDx();
		getDy();
	}
	
	public double getMinX() {
		return minX;
	}
	public void setMinX(double minX) {
		this.minX = minX;
	}
	public double getMaxX() {
		return maxX;
	}
	public void setMaxX(double maxX) {
		this.maxX = maxX;
	}
	public double getMinY() {
		return minY;
	}
	public void setMinY(double minY) {
		this.minY = minY;
	}
	public double getMaxY() {
		return maxY;
	}
	public void setMaxY(double maxY) {
		this.maxY = maxY;
	}
	/**
	 * 获取X轴增量
	 * @return
	 */
	public double getDx() {
		if (dx == null) {
			dx = (maxX - minX) / PARTS;
		}
		return dx;
	}
	/**
	 * 获取Y轴增量
	 * @return
	 */
	public double getDy() {
		if (dy == null) {
			dy = (maxY - minY) / PARTS;
		}
		return dy;
	}
	
	/**
	 * 判断坐标是否在范围内
	 * @param x
	 * @param y
	 * @return
	 */
	public boolean inBounds(double x, double y) {
		if (x < minX || maxX < x || y < minY || maxY < y) {
			return false;
		}
		return true;
	}
	
	/**
	 * 获取x坐标所在象限行号
	 * @param x
	 * @return
	 */
	public Integer getRowNum(double x) {
		if (x < minX || maxX < x) {
			return null;
		}
		if (x - minX < 0) {
			return 0;
		}
		
		int result = (int) Math.floor((x - minX) / dx);
		if (result >= PARTS) {
			return result - 1;
		}
		return result;
	}
	
	/**
	 * 获取y坐标所在象限列号
	 * @param y
	 * @return
	 */
	public Integer getColNum(double y) {
		if (y < minY || maxY < y) {
			return null;
		}
		if (y - minY < 0) {
			return 0;
		}
		int result = (int) Math.floor((y - minY) / dy);
		if (result >= PARTS) {
			return result - 1;
		}
		return result;
	}
	
	/**
	 * 获取坐标所在象限编号
	 * @param x
	 * @param y
	 * @return
	 */
	public int[] getRowColNum(double x, double y) {
		Integer rowNum = getRowNum(x);
		Integer colNum = getColNum(y);
		if (rowNum == null || colNum == null) {
			return null;
		}
		return new int[]{rowNum, colNum};
	}
	
	/**
	 * 获取指定象限的坐标范围
	 * @param rowNum 行数编号
	 * @param colNum 列数编号
	 * @return
	 */
	public Bounds getRectangle(int rowNum, int colNum) {
		double minx = this.minX + this.dx * rowNum;
		double maxx = this.minX + this.dx * (rowNum + 1);
		double miny = this.minY + this.dy * colNum;
		double maxy = this.minY + this.dy * (colNum + 1);
		return new Bounds(minx, maxx, miny, maxy);
		
	}
	
	public static void main(String[] args) {
		Bounds bounds = new Bounds(1D, 4D, 1D, 4D);
		int[] rc = bounds.getRowColNum(4D, 4D);
		System.out.println(rc[0]);
		System.out.println(rc[1]);
	}
	
}

 查询、计算

			for (int i = 0; i < Bounds.PARTS; i++) {
				for (int j = 0; j < Bounds.PARTS; j++) {
					logger.info("i:{}, j:{}", i, j);
					// 获取指定象限的范围,用于查询该象限内的点资源和与之相交的网格
					queryBounds = areaBounds.getRectangle(i, j);
					// 查询该象限内的点资源
					pointList = mpointDao.getPointByBounds(tableName, queryBounds);
					//查询该象限内的网格
					areaList = geoServer.queryAreaByBounds(areaTableName, queryBounds);
					for (BldAreaRes point: pointList) {
						stp++;
						for (Area area: areaList) {
							if (area.getGeo().getBounds().getLeft() <= point.getResX()
									&& area.getGeo().getBounds().getRight() >= point.getResX()
									&& area.getGeo().getBounds().getBottom() <= point.getResY()
									&& area.getGeo().getBounds().getTop() >= point.getResY()) {
								if (pu.withIn(point.getPoint(), area.getLines())) {
									list.add(bart);
									break;
								}
							}
						}
						
						if (stp >= 1000 && stp % 1000 == 0) {
							logger.info("TABLE:{}, COMPLETE:{}", tableName, stp);
						}
						
						// 每超过10000行提交一次,并清空
                        /******************************/					
						
					}
					//最后提交一次
                    /******************************/
				}
			}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用 ECharts 的图表库来创建地图分块伪3D效果。ECharts是一个基于JavaScript的开源可视化库,它提供了丰富的图表类型和交互功能。 要创建地图分块伪3D效果,你可以使用 ECharts 的地图组件和自定义样式。首先,你需要选择一个合适的地图,ECharts提供了一些预定义的地图,或者你也可以自定义自己的地图。 然后,你可以通过设置地图的样式属性来实现伪3D效果。例如,可以使用shadowBlur和shadowColor属性来为地图添加阴影效果,使用emphasis属性来控制鼠标悬停时的样式变化。 此外,你还可以使用ECharts的系列配置项来控制地图的颜色、高亮等效果。通过调整这些配置项,你可以实现地图分块伪3D的视觉效果。 下面是一个简单的示例代码,演示了如何使用ECharts创建地图分块伪3D效果: ```javascript // 引入 ECharts var echarts = require('echarts'); // 初始化地图实例 var myChart = echarts.init(document.getElementById('chart')); // 地图数据 var mapData = [ {name: '北京', value: 100}, {name: '上海', value: 200}, {name: '广州', value: 150}, // 其他省份... ]; // 设置地图的样式和系列配置项 var option = { series: [ { type: 'map', map: 'china', label: { show: true }, itemStyle: { color: '#ccc', borderColor: '#999', borderWidth: 1, emphasis: { shadowBlur: 10, shadowColor: 'rgba(0, 0, 0, 0.5)' } }, data: mapData } ] }; // 使用配置项初始化图表 myChart.setOption(option); ``` 以上代码中,我们通过设置地图的itemStyle属性来实现了地图分块伪3D的效果,其中使用了阴影效果和自定义的颜色。 希望这个示例能帮助你实现地图分块伪3D效果。如果你还有其他问题,请随时提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值