多种方法实现热力图(百度API、ArcGIS API、leaflet API 和 QGIS、Kepler.gl

# 原理

    热力图原理:为离散点信息创建一个Mask。Mask是一个圆形区域,半径为该点可以对最终热力图像产生影响的区域半径。中心点的权重为1,越向边缘辐射,权重越低,边缘部分的权重为0。Mask的渐变过程可以考虑多种形式,如线性变化,二次曲线等。将所有离散点Mask进行叠加,产生一幅灰度图像。相邻Mask的重叠部分进行权重累加操作,最终灰度图中每个像素点的数值大小就是所有和其有关的Mask中的权重之和。 离散点密度越高的地方,灰度图种像素点数值越高,即图像越亮。根据具体项目不同,可考虑将权重乘上一个固定系数。将生成的灰度图映射到彩色图像上。

# 数据

    实现将收集的POI数据进行热力图可视化   

    数据:北京市旅游景点.xls

      导入至mysql数据库

    本文实现了由JavaScript API 和 非代码形式生成热力图的方法。 

#1# 百度地图JavaScript API

    百度地图热力图API:地图JS API示例 | 百度地图开放平台

<%@ page language="java" contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>
<head>
   <meta charset="UTF-8">
   <title>热力图</title>
   <style type="text/css">
html {
	height: 100%
}

body {
	height: 100%;
	margin: 0px;
	padding: 0px
}

#map {
	height: 100%
}
   </style>

<script type="text/javascript"  src="//api.map.baidu.com/api?v=2.0&ak=密钥"></script>
<script type="text/javascript"  src="//api.map.baidu.com/library/Heatmap/2.0/src/Heatmap_min.js"></script>

</head>
<body>
	<div id="map"></div>

	<%@ page import="java.sql.*"%>
	<%@ page import="java.io.PrintWriter"%>
	<%
		request.setCharacterEncoding("utf-8");
		Connection con;
		Statement stmt = null;
		ResultSet rs;
		String all = "";

		try {
			Class.forName("com.mysql.cj.jdbc.Driver");
			System.out.println("数据库连线成功");
		} catch (Exception e) {
			System.out.println("数据库连线失败");
		}
		try {
			String url = "jdbc:mysql://127.0.0.1:3306/scenery?serverTimezone=UTC";
			String user = "root";
			String password = "123456";
			con = DriverManager.getConnection(url, user, password);
			stmt = con.createStatement();
			System.out.println("成功连接到本地数据库");
		} catch (Exception e) {
			System.out.println("本地数据库连接失败");
		}

		try {
			rs = stmt.executeQuery("select * from ScenerySpot");
			while (rs.next()) {
				double lat = rs.getDouble("Latitude");
				double lng = rs.getDouble("Longitude");
				String s = lng + "," + lat + ";";
				all = all + s;
			}
		} catch (Exception e) {
			System.out.println("数据获取失败");
			System.out.println(e);
		}
	%>

</body>

<script>
    var d = '<%=all%>'
	var poi = d.split(';');//解析字符串
	var pointList = new Array();
	for (var i = 0; i < poi.length; i++) {
		var points = poi[i].split(',');
		var data = {};
		data.lng = points[0];
		data.lat = points[1];
		data.count = 20;
		pointList.push(data);
	}

	//判断浏览区是否支持canvas
	function isSupportCanvas() {
		var elem = document.createElement('canvas');
		return !!(elem.getContext && elem.getContext('2d'));
	}
	//alert(isSupportCanvas())

	var map = new BMap.Map("map");
	var point = new BMap.Point(116.418261, 39.921984);
	map.centerAndZoom(point, 10); // 初始化地图,设置中心点坐标和地图级别
	map.enableScrollWheelZoom(); // 允许滚轮缩放
	
	var heatmapOverlay = new BMapLib.HeatmapOverlay({
		"radius" : 20
	});

	map.addOverlay(heatmapOverlay);

	heatmapOverlay.setDataSet({
		data : pointList,
		max : 100
	});
</script>
</html>

#2# ArcGIS API for JavaScript

【4.14版本热力图实现】
https://developers.arcgis.com/javascript/latest/sample-code/visualization-heatmap/index.html

【3.x版本热力图实现】
https://developers.arcgis.com/javascript/3/jssamples/renderer_heatmap.html

【featureLayer】
https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />

    <title>Visualize points with a heatmap - 4.14</title>

    <link rel="stylesheet" href="https://js.arcgis.com/4.14/esri/themes/light/main.css" />

    <style>
        html,
        body,
        #viewDiv {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
        }
    </style>

    <script src="https://js.arcgis.com/4.14/"></script>

    <script>
        require([
            "esri/Map",
            "esri/layers/CSVLayer",
            "esri/views/MapView",
            "esri/layers/TileLayer"
        ], function (Map, CSVLayer, MapView, TileLayer) {
            var url =
                "https://xxxxxxxx/mmm.csv";
            
            var renderer = {
                type: "heatmap",
                colorStops: [
                    { color: "rgba(63, 40, 102, 0)", ratio: 0 },
                    { color: "#472b77", ratio: 0.083 },
                    { color: "#4e2d87", ratio: 0.166 },
                    { color: "#563098", ratio: 0.249 },
                    { color: "#5d32a8", ratio: 0.332 },
                    { color: "#6735be", ratio: 0.415 },
                    { color: "#7139d4", ratio: 0.498 },
                    { color: "#7b3ce9", ratio: 0.581 },
                    { color: "#853fff", ratio: 0.664 },
                    { color: "#a46fbf", ratio: 0.747 },
                    { color: "#c29f80", ratio: 0.83 },
                    { color: "#e0cf40", ratio: 0.913 },
                    { color: "#ffff00", ratio: 1 }
                ],
                maxPixelIntensity: 25,
                minPixelIntensity: 0
            };

            var layer = new CSVLayer({
                url: url,
                renderer: renderer
            });
            
            var baselayer = new TileLayer({
                url: "https://map.geoq.cn/arcgis/rest/services/ChinaOnlineCommunity/MapServer"
            });

            var map = new Map({
                layers: [baselayer]
            });
            map.layers.add(layer)

            var view = new MapView({
                container: "viewDiv",
                center: [116.418261, 39.921984],
                zoom: 10,
                map: map
            });

        });
    </script>
</head>

<body>
    <div id="viewDiv"></div>
</body>

</html>

#3# leaflet

    入门基础:leaflet:入门基础(一)_Dawn_www的博客-CSDN博客_leaflet

    需要的文件:heatmap.js      leaflet-heatmap.js     leaflet.js     leaflet.css

    heatmap文件下载地址:heatmap.js Download

    文件分别在:build文件夹下的heatmap.js       plugins > leaflet-heatmap文件夹下的leaflet-heatmap.js

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>leaflet热力图</title>

<style>
#mapid {
	height: 600px;
}
</style>

<link rel="stylesheet"
	href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css" />

<script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"></script>
<script src="./heatmap.js"></script>
<script src="./leaflet-heatmap.js"></script>
</head>
<body>
	<div id="mapid"></div>

	<%@ page import="java.sql.*"%>
	<%@ page import="java.io.PrintWriter"%>

	<%
		request.setCharacterEncoding("utf-8");
		Connection con;
		Statement stmt = null;
		ResultSet rs;
		String all = "";

		try {
			Class.forName("com.mysql.cj.jdbc.Driver");
			System.out.println("数据库连线成功");
		} catch (Exception e) {
			System.out.println("数据库连线失败");
		}
		try {
			String url = "jdbc:mysql://127.0.0.1:3306/scenery?serverTimezone=UTC";
			String user = "root";
			String password = "123456";
			con = DriverManager.getConnection(url, user, password);
			stmt = con.createStatement();
			System.out.println("成功连接到本地数据库");
		} catch (Exception e) {
			System.out.println("本地数据库连接失败");
		}

		try {
			rs = stmt.executeQuery("select * from ScenerySpot");
			while (rs.next()) {
				double lat = rs.getDouble("Latitude");
				double lng = rs.getDouble("Longitude");
				String s = lng + "," + lat + ";";
				all = all + s;
			}
		} catch (Exception e) {
			System.out.println("数据获取失败");
			System.out.println(e);
		}
	%>

</body>

<script>
    var d = '<%=all%>'
	var poi = d.split(';');//解析字符串
	
 	var arraySpot = new Array();	 		//构建json数组中的对象		
	
	for (var i = 0; i < poi.length; i++) {
		var points = poi[i].split(',');
		var data = {};
		data.lng = parseFloat(points[0]);
		data.lat = parseFloat(points[1]);
		data.count = 1;
		arraySpot.push(data);
	}
 	
/* 	var k =JSON.stringify(arraySpot);
	alert(k); */
 
    var ks = [{ "lat": 39.998547, "lng":116.274853, "count": 1},
        { "lat": 39.886376, "lng": 116.417115, "count": 1 },
        { "lat": 40.364396, "lng": 116.014538, "count": 1 },
        { "lat": 40.420718, "lng": 116.473875, "count": 1 },
        { "lat": 40.29995, "lng": 116.234183, "count": 1 },
        { "lat": 39.924091, "lng": 116.403414, "count": 1 },
        { "lat": 40.02523, "lng": 116.396797, "count": 1 },
    ];
    
  
	//数据
	var testData = {
		max : 20, 
		data : ks // arraySpot
	};  

	//配置
	var cfg = {
		"radius" : 0.1,
		"maxOpacity" : .2, //设置最大的不透明度
		"scaleRadius" : true, //设置热力点是否平滑过渡
		"useLocalExtrema" : true,//使用局部极值
		latField : 'lat',
		lngField : 'lng',
		valueField : 'count'
	};

	var heatmapLayer = new HeatmapOverlay(cfg);

	//图层
	var baseLayer = L.tileLayer(
			'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
				attribution : '...',
				maxZoom : 18
			});

	var map = new L.Map('mapid', {
		center : new L.LatLng(39.56, 116.20),
		zoom : 9,
		layers : [ baseLayer,heatmapLayer ]
	});

	heatmapLayer.setData(testData);
	
</script>
</html>

    这里遇到一个问题:读取数据库数据并按格式组织好后,运行却没有显示热力图(只有底图),但手工输入的数据却可以生成热力图,不知道是不是组织的格式不对,等之后解决了再上传。

    其他:半径的设置要合理,之前设置为1,结果热力图挤成一团

#4# QGIS

    如果不会写JavaScript,还有方法生成热力图。

    1.将数据转换为csv格式,utf-8编码

    2.打开QGIS,选择【图层】-【添加图层】-【添加文本数据图层】

    (注:这里坐标系为了方便选用了wgs84,但百度的坐标是火星坐标系 ,后续需要进行坐标系转换

        3.打开图层属性,选择符号化,设置为热图,并进行颜色设置

    4.效果如图所示

    QGIS制作热力图教程:製作熱區圖 (QGIS3)

#5# Kepler.gl

    入门基础:Kepler.gl_Dawn_www的博客-CSDN博客_kepler.gl

     注:经纬度字段要用英文lat latitude lng longitude,否则无法自动识别

    

    2020年7月更新:最近又看到一个可以生成热力图的方法:高德开放平台 | Map Lab

# 其他

     免费文件存储分享服务汇总:免费文件存储分享服务汇总 - 梁Sir's Blog

    QGIS:如何美化数据的呈现效果

<think>好的,我现在需要处理用户关于城市路网数据可视化的技术实现工具的查询。首先,我得先仔细理解用户的问题。用户提到想寻找相关的技术实现方法或工具,特别是结合了引用中的信息,比如使用Python、networkX、OpenStreetMap等。引用中提到的交通数据可视化方法、路网图绘制以及未来趋势中的3D建模数字孪生技术,这些都需要涵盖进去。 接下来,我应该回顾用户提供的三个引用内容。引用[1]提到Python实现交通数据可视化的方法,引用[2]具体说明使用Python+networkX+OpenStreetMap画交通路网图,引用[3]则讨论了数据可视化的发展趋势,包括3D建模数字孪生。因此,回答需要覆盖现有工具技术,以及未来的趋势。 首先,我需要列出常用的工具技术,比如Python库(如networkX、osmnx、folium、matplotlib)、GIS工具(如QGISArcGIS)、三维可视化工具(如Three.js、Blender、Unity),以及大数据处理平台(如Hadoop、Spark)。同时,还要提到OpenStreetMap作为数据源的重要性,以及如何利用API或osmnx库获取数据。 然后,具体的技术实现步骤可能需要分点说明,比如数据获取、处理、可视化等步骤,每个步骤中使用的工具方法。例如,数据获取可以使用OpenStreetMap的API或osmnx,数据处理用pandas或GeoPandas,可视化用上述提到的库工具。 另外,用户可能对实际代码示例感兴趣,所以需要提供一个简单的Python示例,展示如何使用osmnxmatplotlib绘制路网图。同时,要提到更复杂的应用,比如结合交通流量数据或3D可视化。 还要考虑引用中的未来趋势,如数字孪生3D建模,所以需要补充这些方向,推荐相应的工具如CesiumJS、Unity等,并说明它们如何应用于城市路网的可视化。 最后,生成相关问题,这些问题应该围绕用户可能进一步感兴趣的方面,比如如何获取实时交通数据、3D可视化的工具比较、大数据处理的具体方法,以及数字孪生技术的应用案例。 需要注意的是,回答要符合系统级指令,比如行内公式用$...$,独立公式用$$...$$,但在这个问题中可能涉及数学公式较少,所以可能不需要太多。同时,确保中文回答,结构清晰,分点说明,并在引用处自然添加标识符。例如,在提到交通数据可视化的重要性时,引用[^1],在提到OpenStreetMapPython实现时引用[^2],在趋势部分引用[^3]。 现在需要检查是否有遗漏的技术或工具,比如可能还有其他的GIS工具或库,或者数据处理的步骤是否需要更详细说明。另外,确保每个部分都结合了引用中的内容,以增强回答的可信度相关性。 总结来说,回答的结构应该是:概述、常用工具与技术(分点)、技术实现步骤(分步骤)、示例代码、未来趋势、相关问题。每个部分引用相应的来源,并保持语言自然流畅。</think>### 城市路网数据可视化技术实现方法与工具 城市路网可视化主要依赖地理信息系统(GIS)、开源地图数据及编程工具,结合数据处理图形渲染技术实现。以下是具体方法及工具分类: --- #### 一、常用工具与技术 1. **Python生态工具** - **`osmnx` + `networkX`**:通过`osmnx`从OpenStreetMap(OSM)获取城市路网数据,转换为网络图结构,再利用`networkX`进行拓扑分析或路径规划。 - **`folium`/`geopandas`**:结合`geopandas`处理地理数据,用`folium`生成交互式Leaflet地图,支持路网叠加力图或流量动画。 - **`matplotlib`/`plotly`**:用于静态或动态2D/3D路网渲染,适合学术论文或简单分析场景。 2. **GIS专业软件** - **QGIS/ArcGIS**:支持导入OSM数据或Shapefile格式路网,提供符号化编辑、空间分析及可视化模板,适合非编程用户[^2]。 - **Kepler.gl**:基于Web的交互式工具,可直接上传CSV/GeoJSON数据生成动态可视化效果。 3. **三维与实时渲染** - **Three.js/CesiumJS**:通过WebGL实现浏览器端3D路网渲染,支持光照、纹理动态数据更新[^3]。 - **Unity/Unreal Engine**:用于高精度数字孪生场景,结合实时交通数据构建虚拟城市模型[^3]。 --- #### 二、技术实现步骤 1. **数据获取** - 从OpenStreetMap下载路网数据(如`.osm`格式),或通过API实时调用(如`osmnx`库的`graph_from_place`函数)。 - 示例代码(Python): ```python import osmnx as ox city_road = ox.graph_from_place("Beijing, China", network_type="drive") ox.plot_graph(city_road) ``` 2. **数据处理** - 使用`pandas`清洗数据,或通过`GeoPandas`转换坐标系(如WGS84转Web Mercator)。 - 提取关键属性:道路等级、车道数、实时车速等。 3. **可视化实现** - **基础路网**:用`networkX`绘制拓扑图,或通过QGIS加载OSM数据生成分层地图。 - **增强效果**:叠加交通流量力图(`folium.plugins.HeatMap`)或动画轨迹(`plotly.express.line_mapbox`)。 --- #### 三、未来趋势 结合引用[3],未来路网可视化将更注重**多维融合**与**智能交互**: - **数字孪生**:通过BIM+GIS技术构建城市级3D模型,整合实时传感器数据。 - **AI增强**:利用机器学习预测拥堵,并在可视化中动态标注风险点。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值