首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

Mapbox添加行政区矢量图层,Mapbox添加分级设色图层,Mapbox添加文本标记图层,Mapbox给行政区矢量数据添加名称,Mapbox自定义鼠标悬浮框,Mapbox添加天地图底图

  • 25-02-22 02:41
  • 4139
  • 7885
blog.csdn.net

目录

一、Mapbox简介

二、Mapbox添加地图、各数据图层和功能的思路

2.1、添加天地图底图

2.2、Mapbox添加行政区矢量图层

2.3、Mapbox添加分级设色图层

2.4、Mapbox添加文本标记图层

2.5、Mapbox自定义鼠标悬浮框

三、最终效果及代码展示

3.1、最终效果

3.2、完整代码展示:

3.2.1、map.vue(map所在的组件):

3.2.2、mapbox.js:

四、总结


一、Mapbox简介

        Mapbox 是一家提供定制地图服务的公司,它允许开发者和设计师通过其平台创建和部署个性化的地图。Mapbox 提供了一整套地图工具和API,使得用户可以轻松地在网站、移动应用和各种设备上集成地图服务。

        以下是Mapbox的一些主要特点:

  1. 定制化:Mapbox 允许用户根据自己的品牌和设计需求定制地图样式,包括颜色、图标、字体等。

  2. 数据驱动:Mapbox 支持使用各种数据源,包括开放街道地图(OpenStreetMap)数据,以及其他商业和私有数据。

  3. 实时更新:Mapbox 提供的地图服务可以实时更新,确保地图信息的准确性和最新性。

  4. 多平台支持:Mapbox 的API和服务支持多种平台和语言,包括Web、iOS、Android等。

  5. 交互式地图:Mapbox 支持创建交互式地图,用户可以添加图层、标记、路径、热力图等。

  6. 位置服务:Mapbox 提供了一套完整的位置服务,包括地理编码、逆地理编码、方向和路由规划等。

  7. 地图分析:Mapbox 提供地图分析工具,帮助用户理解用户行为和地图数据。

  8. 社区和生态系统:Mapbox 拥有一个活跃的开发者社区,提供了大量的教程、文档和论坛支持。

  9. 安全性:Mapbox 提供了安全措施,如访问控制和数据加密,以保护用户数据的安全。

  10. 可扩展性:Mapbox 的服务设计为可扩展的,可以支持从小规模到大规模的地图应用。

  11. 企业解决方案:Mapbox 为企业提供定制化的解决方案,满足特定业务需求。

  12. 集成第三方服务:Mapbox 可以与许多第三方服务和API集成,如天气、交通、社交网络等。

  13. 地图编辑工具:Mapbox 提供了地图编辑工具,允许用户直接在地图上添加或修改数据。

  14. 地图SDK:Mapbox 提供了软件开发工具包(SDK),使得开发者可以快速地在自己的应用中集成地图功能。

        Mapbox 的服务通常是基于订阅模式的,用户根据自己的使用量和需求选择合适的订阅计划。Mapbox 的服务广泛应用于交通、物流、房地产、旅游、城市规划等多个领域。通过Mapbox,用户可以创建出既美观又功能强大的地图应用。

二、Mapbox添加地图、各数据图层和功能的思路

2.1、添加天地图底图

         mapbox导入天地图比较复杂,如下代码所示,配置一个配置项,然后在初始化的时候放到设置底图的位置即可。

  1. // 将天地图作为底图
  2. const vecUrl =
  3. // "http://t0.tianditu.gov.cn/vec_w/wmts?tk=yourtoken";
  4. "http://t0.tianditu.gov.cn/vec_w/wmts?tk=yourtoken";
  5. const cvaUrl =
  6. // "http://t0.tianditu.gov.cn/cva_w/wmts?tk=yourtoken";
  7. "http://t0.tianditu.gov.cn/cva_w/wmts?tk=yourtoken";
  8. //实例化source对象
  9. var tdtVec = {
  10. //类型为栅格瓦片
  11. type: "raster",
  12. tiles: [
  13. //请求地址
  14. vecUrl +
  15. "&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=tiles",
  16. ],
  17. crossOrigin: "anonymous",
  18. //分辨率
  19. tileSize: 256,
  20. };
  21. var tdtCva = {
  22. type: "raster",
  23. tiles: [
  24. cvaUrl +
  25. "&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=tiles",
  26. ],
  27. tileSize: 256,
  28. };
  29. var style = {
  30. //设置版本号,一定要设置
  31. version: 8,
  32. //添加来源
  33. sources: {
  34. tdtVec: tdtVec,
  35. tdtCva: tdtCva,
  36. },
  37. layers: [
  38. {
  39. //图层id,要保证唯一性
  40. id: "tdtVec",
  41. //图层类型
  42. type: "raster",
  43. //数据源
  44. source: "tdtVec",
  45. //图层最小缩放级数
  46. minzoom: 0,
  47. //图层最大缩放级数
  48. maxzoom: 17,
  49. },
  50. {
  51. id: "tdtCva",
  52. type: "raster",
  53. source: "tdtCva",
  54. minzoom: 0,
  55. maxzoom: 17,
  56. },
  57. ],
  58. glyphs: "mapbox://fonts/mapbox/{fontstack}/{range}.pbf",
  59. };
  60. export function loadMap(box) {
  61. map = new mapboxgl.Map({
  62. container: box,
  63. // 导入设置好的天地图配置
  64. style: style,
  65. preserveDrawingBuffer: true,
  66. center: [114, 30],
  67. zoom: 4,
  68. });
  69. }

2.2、Mapbox添加行政区矢量图层

        这个很简单,主要是需要行政区边界的geojson,这个一般是用shpfile文件转化为geojson,可以通过这个在线网站实现:mapshaper

        代码实现,先完成geojson数据源添加,然后添加一个矢量边界图层就可以了。

  1. export function loadMap(box) {
  2. map = new mapboxgl.Map({
  3. container: box,
  4. // style: 'mapbox://styles/mapbox/streets-v11',
  5. // style: 'mapbox://styles/examples/cjgioozof002u2sr5k7t14dim',
  6. style: style,
  7. preserveDrawingBuffer: true,
  8. center: [114, 30],
  9. zoom: 4,
  10. });
  11. }
  12. export function addGeoJson() {
  13. map.on("style.load", () => {
  14. // 加载 GeoJSON 数据源
  15. map.addSource("geojsonSource", {
  16. type: "geojson",
  17. data: CityData,
  18. });
  19. // 添加图层来显示行政区划的边界
  20. map.addLayer({
  21. id: "lineLayer",
  22. type: "line",
  23. source: "geojsonSource",
  24. paint: {
  25. "line-color": "#FFF",
  26. "line-width": 1.5,
  27. },
  28. });
  29. });
  30. }

2.3、Mapbox添加分级设色图层

        分级设色本质是为了直观的体现不同的等级或者不同的数值:

  • 体现不同的等级:根据数值的极差分档,类似于arcgis的重分类,不同档位设置不同的颜色
  • 体现不同的数值:根据数值的极差用颜色渐变平滑的展示数值的区别,一目了然可任意两两比较。

        这里展示的是体现不同的数值的写法:

  1. export function loadMap(box) {
  2. map = new mapboxgl.Map({
  3. container: box,
  4. // style: 'mapbox://styles/mapbox/streets-v11',
  5. // style: 'mapbox://styles/examples/cjgioozof002u2sr5k7t14dim',
  6. style: style,
  7. preserveDrawingBuffer: true,
  8. center: [114, 30],
  9. zoom: 4,
  10. });
  11. }
  12. // 根据value值上色
  13. export function paintMap() {
  14. // 添加图层来上色
  15. map.addLayer({
  16. id: "geojsonLayer",
  17. type: "fill", // 根据你的数据类型设置合适的图层类型,比如 'fill'、'circle'、'line' 等
  18. source: "geojsonSource",
  19. paint: {
  20. "fill-color": [
  21. "match",
  22. //在geojson中获取name属性
  23. ["get", "name"],
  24. //将geojson中的name属性与cityValueData进行匹配,得到正确的综合得分,并根据colorRanges的情况上色
  25. ...rankingFormatted.reduce((acc, data) => {
  26. return [...acc, data.cityName, getColor2(data.score)];
  27. }, []),
  28. "#000000", // 默认颜色
  29. ],
  30. "fill-opacity": 1, // 填充透明度
  31. },
  32. });
  33. }
  34. // 设置颜色范围
  35. // const colorRange = ['#ADD8E6','#00008B'];
  36. const colorRange = ["#DBEEF6", "#36869A"];
  37. const colorRangeMin = ["#E2F0D9", "#385723"];
  38. const innovation = ["#fff4f8", "#dc7d61"];
  39. const operation = ["#e0e5e9", "#73a9d7"];
  40. const green = ["#e9f0e8", "#80c67d"];
  41. const share = ["#fff8eb", "#f6bb81"];
  42. const open = ["#eaebff", "#b67ebd"];
  43. // 创建颜色插值函数(综合得分)
  44. const colorInterpolate = chroma.scale(colorRange).domain([37, 90]);
  45. // 创建颜色插值函数(单指标得分)
  46. const colorInterpolateMin = chroma.scale(colorRangeMin).domain([1.5, 20]);
  47. const colorInnovation = chroma.scale(innovation).domain([4.1, 17.4]);
  48. const colorOperation = chroma.scale(operation).domain([9.4, 18.7]);
  49. const colorGreen = chroma.scale(green).domain([9.2, 18]);
  50. const colorOpen = chroma.scale(open).domain([1.6, 20]);
  51. const colorShare = chroma.scale(share).domain([7.5, 20]);
  52. // 根据城市值获取对应颜色
  53. function getColor2(value, type) {
  54. if (value > 20) {
  55. return colorInterpolate(value).hex();
  56. } else {
  57. switch (type) {
  58. case 0:
  59. return colorInnovation(value).hex();
  60. case 1:
  61. return colorOperation(value).hex();
  62. case 2:
  63. return colorGreen(value).hex();
  64. case 3:
  65. return colorShare(value).hex();
  66. case 4:
  67. return colorOpen(value).hex();
  68. default:
  69. break;
  70. }
  71. // return colorInterpolateMin(value).hex();
  72. }
  73. }

2.4、Mapbox添加文本标记图层

        底图嘛,只有矢量边界不够直观,底图信息又会被颜色图层盖住,所以需要在最上方添加文本注记图层,当然也可以添加一些别的文本内容,标记等都可以。

        这里有一个额外引入的数据源,是一个点shpfile转化的geojson,这个点是用来规定显示文本注记的位置的,也可以直接在原先面数据源的基础上使用文本注记,那么文本注记会直接显示在每一个闭合曲线(拓扑展现就是一个面)上显示。

  1. export function loadMap(box) {
  2. map = new mapboxgl.Map({
  3. container: box,
  4. // style: 'mapbox://styles/mapbox/streets-v11',
  5. // style: 'mapbox://styles/examples/cjgioozof002u2sr5k7t14dim',
  6. style: style,
  7. preserveDrawingBuffer: true,
  8. center: [114, 30],
  9. zoom: 4,
  10. });
  11. }
  12. export function addGeoJson() {
  13. map.on("style.load", () => {
  14. map.addSource("pointGeojsonSource", {
  15. type: "geojson",
  16. data: cityPoint,
  17. });
  18. // 添加symbol图层以显示文本
  19. map.addLayer({
  20. id: "pointLabel",
  21. type: "symbol",
  22. source: "pointGeojsonSource",
  23. layout: {
  24. "text-field": ["get", "name"], // 使用get表达式来获取"title"属性
  25. "text-size": 14,
  26. "text-variable-anchor": ["top", "bottom", "left", "right"],
  27. "text-radial-offset": 0.5,
  28. "text-justify": "auto",
  29. },
  30. paint: {
  31. "text-color": "#000", // 文本颜色
  32. "text-halo-color": "#FFF", // 文本描边颜色
  33. "text-halo-width": 1, // 文本描边宽度
  34. },
  35. });
  36. });
  37. }

2.5、Mapbox自定义鼠标悬浮框

        鼠标悬浮框主要是增加地图图层的互动效果,用于展示更多的信息。

  1. // 在鼠标移动到地图上显示信息
  2. let popup = null;
  3. function showPopup(e, value) {
  4. const features = e.features;
  5. if (features.length > 0) {
  6. map.getCanvas().style.cursor = "pointer";
  7. const cityName = features[0].properties.name; // 城市名称
  8. const cityValue = getCityValue(cityName, value); // 获取对应的值
  9. if (popup) {
  10. popup.remove();
  11. }
  12. // 在页面上显示浮动信息
  13. popup = new mapboxgl.Popup()
  14. .setLngLat(e.lngLat)
  15. .setHTML(`${cityName}
    评分为: ${cityValue}`
    )
  16. .addTo(map);
  17. } else {
  18. map.getCanvas().style.cursor = "";
  19. }
  20. }
  21. // 在鼠标移出时移除浮动信息
  22. function removePopup() {
  23. if (popup) {
  24. popup.remove();
  25. }
  26. map.getCanvas().style.cursor = "";
  27. }
  28. // 绑定地图交互事件,鼠标悬浮和移出事件
  29. function bindMapInteractions(value) {
  30. map.off("mousemove", "geojsonLayer", showPopup);
  31. map.on("mousemove", "geojsonLayer", (e) => showPopup(e, value));
  32. map.off("mouseout", "geojsonLayer", removePopup);
  33. map.on("mouseout", "geojsonLayer", removePopup);
  34. }

三、最终效果及代码展示

3.1、最终效果

包括天地图底图,行政区矢量边界图层,分层设色图层,文本标记图层,还有鼠标悬浮框(不包括图例)在内的综合效果。

3.2、完整代码展示:

3.2.1、map.vue(map所在的组件):

  1. <template>
  2. <div class="mapboxBorder">
  3. <div
  4. id="mapbox"
  5. style="width: 100%; height: 100%; border-radius: 18px"
  6. >div>
  7. div>
  8. template>
  9. <script setup>
  10. import { map, loadMap, addGeoJson, updateMap } from "@/utils/mapbox.js";
  11. import { onMounted, ref, watch } from "vue";
  12. const initMapbox = () => {
  13. loadMap("mapbox");
  14. map.setCenter([119.14, 31.22]); //修改地图中心点
  15. map.setZoom(6.4); //设置缩放级别
  16. };
  17. onMounted(() => {
  18. //挂载mapbox
  19. initMapbox();
  20. //添加矢量图层
  21. addGeoJson();
  22. });
  23. // ...map组件中的其他事件内容
  24. script>

3.2.2、mapbox.js:

  1. import mapboxgl from "mapbox-gl";
  2. import "mapbox-gl/dist/mapbox-gl.css";
  3. // import MapboxLanguage from "@mapbox/mapbox-gl-language";
  4. import CityData from "@/assets/json/standardCityBoundary.json";
  5. import ranking from "@/assets/json/scoreDetail.json";
  6. import { scoreFormat } from "@/utils/format.ts";
  7. import cityPoint from "@/assets/json/cityCenterPoint.json";
  8. const rankingFormatted = scoreFormat(ranking);
  9. mapboxgl.accessToken =
  10. "yourtoken"; //去mapbox官⽹申请
  11. const colorRanges = [
  12. { min: 0, max: 45, color: "#E31A1C" },
  13. { min: 45, max: 55, color: "#FEB24C" },
  14. { min: 55, max: 70, color: "#FFEDA0" },
  15. { min: 70, max: 100, color: "#90EE90" },
  16. ];
  17. const colorRangesSingle = [
  18. { min: 0, max: 5, color: "#E31A1C" },
  19. { min: 5, max: 10, color: "#FEB24C" },
  20. { min: 10, max: 15, color: "#FFEDA0" },
  21. { min: 15, max: 20, color: "#90EE90" },
  22. ];
  23. // 将天地图作为底图
  24. const vecUrl =
  25. // "http://t0.tianditu.gov.cn/vec_w/wmts?tk=yourtoken";
  26. "http://t0.tianditu.gov.cn/vec_w/wmts?tk=yourtoken";
  27. const cvaUrl =
  28. // "http://t0.tianditu.gov.cn/cva_w/wmts?tk=yourtoken";
  29. "http://t0.tianditu.gov.cn/cva_w/wmts?tk=yourtoken";
  30. //实例化source对象
  31. var tdtVec = {
  32. //类型为栅格瓦片
  33. type: "raster",
  34. tiles: [
  35. //请求地址
  36. vecUrl +
  37. "&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=tiles",
  38. ],
  39. crossOrigin: "anonymous",
  40. //分辨率
  41. tileSize: 256,
  42. };
  43. var tdtCva = {
  44. type: "raster",
  45. tiles: [
  46. cvaUrl +
  47. "&SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=tiles",
  48. ],
  49. tileSize: 256,
  50. };
  51. var style = {
  52. //设置版本号,一定要设置
  53. version: 8,
  54. //添加来源
  55. sources: {
  56. tdtVec: tdtVec,
  57. tdtCva: tdtCva,
  58. },
  59. layers: [
  60. {
  61. //图层id,要保证唯一性
  62. id: "tdtVec",
  63. //图层类型
  64. type: "raster",
  65. //数据源
  66. source: "tdtVec",
  67. //图层最小缩放级数
  68. minzoom: 0,
  69. //图层最大缩放级数
  70. maxzoom: 17,
  71. },
  72. {
  73. id: "tdtCva",
  74. type: "raster",
  75. source: "tdtCva",
  76. minzoom: 0,
  77. maxzoom: 17,
  78. },
  79. ],
  80. glyphs: "mapbox://fonts/mapbox/{fontstack}/{range}.pbf",
  81. };
  82. export let map = null; // 导出 map 对象
  83. export function loadMap(box) {
  84. map = new mapboxgl.Map({
  85. container: box,
  86. // style: 'mapbox://styles/mapbox/streets-v11',
  87. // style: 'mapbox://styles/examples/cjgioozof002u2sr5k7t14dim',
  88. style: style,
  89. preserveDrawingBuffer: true,
  90. center: [114, 30],
  91. zoom: 4,
  92. });
  93. // 设置汉化
  94. // map.addControl(new MapboxLanguage({
  95. // defaultLanguage: 'zh-Hans'
  96. // }));
  97. }
  98. export function addGeoJson() {
  99. map.on("style.load", () => {
  100. // 加载 GeoJSON 数据源
  101. map.addSource("geojsonSource", {
  102. type: "geojson",
  103. data: CityData,
  104. });
  105. map.addSource("pointGeojsonSource", {
  106. // 注意:这里使用的是不同的ID
  107. type: "geojson",
  108. data: cityPoint,
  109. });
  110. //初始化上色
  111. paintMap();
  112. //绑定地图事件
  113. bindMapInteractions();
  114. // 添加图层来显示行政区划的边界
  115. map.addLayer({
  116. id: "lineLayer",
  117. type: "line",
  118. source: "geojsonSource",
  119. paint: {
  120. "line-color": "#FFF",
  121. "line-width": 1.5,
  122. },
  123. });
  124. // 添加symbol图层以显示文本
  125. map.addLayer({
  126. id: "pointLabel",
  127. type: "symbol",
  128. source: "pointGeojsonSource",
  129. layout: {
  130. "text-field": ["get", "name"], // 使用get表达式来获取"title"属性
  131. "text-size": 14,
  132. "text-variable-anchor": ["top", "bottom", "left", "right"],
  133. "text-radial-offset": 0.5,
  134. "text-justify": "auto",
  135. },
  136. paint: {
  137. "text-color": "#000", // 文本颜色
  138. "text-halo-color": "#FFF", // 文本描边颜色
  139. "text-halo-width": 1, // 文本描边宽度
  140. },
  141. });
  142. // 添加地级市名称的文本图层
  143. // map.addLayer({
  144. // id: "cityNameLayer",
  145. // type: "symbol",
  146. // source: "geojsonSource",
  147. // layout: {
  148. // "text-field": [
  149. // "match",
  150. // ["get", "is_island"],
  151. // "true",
  152. // "", // 如果是群岛城市,不显示名字
  153. // ["get", "name"], // 如果不是群岛城市,显示名字
  154. // ],
  155. // "text-size": 14,
  156. // "text-variable-anchor": ["top", "bottom", "left", "right"],
  157. // "text-radial-offset": 0.5,
  158. // "text-justify": "auto",
  159. // "text-allow-overlap": false, // 不允许文本标签重叠
  160. // },
  161. // paint: {
  162. // "text-color": "#000", // 文本颜色
  163. // "text-halo-color": "#FFF", // 文本描边颜色
  164. // "text-halo-width": 1, // 文本描边宽度
  165. // },
  166. // });
  167. });
  168. }
  169. // 根据value值上色
  170. export function paintMap() {
  171. // 添加图层来上色
  172. map.addLayer({
  173. id: "geojsonLayer",
  174. type: "fill", // 根据你的数据类型设置合适的图层类型,比如 'fill'、'circle'、'line' 等
  175. source: "geojsonSource",
  176. paint: {
  177. "fill-color": [
  178. "match",
  179. //在geojson中获取name属性
  180. ["get", "name"],
  181. //将geojson中的name属性与cityValueData进行匹配,得到正确的综合得分,并根据colorRanges的情况上色
  182. ...rankingFormatted.reduce((acc, data) => {
  183. return [...acc, data.cityName, getColor2(data.score)];
  184. }, []),
  185. "#000000", // 默认颜色
  186. ],
  187. "fill-opacity": 1, // 填充透明度
  188. },
  189. });
  190. }
  191. // 切换数据更新地图上色
  192. export function updateMap(value) {
  193. // 根据新的 value 更新绘制属性
  194. let propertiesSelect = "";
  195. switch (parseInt(value)) {
  196. case 0:
  197. propertiesSelect = "创新发展";
  198. break;
  199. case 1:
  200. propertiesSelect = "协调发展";
  201. break;
  202. case 2:
  203. propertiesSelect = "绿色发展";
  204. break;
  205. case 3:
  206. propertiesSelect = "开放发展";
  207. break;
  208. case 4:
  209. propertiesSelect = "共享发展";
  210. break;
  211. case 5:
  212. propertiesSelect = "score";
  213. break;
  214. default:
  215. break;
  216. }
  217. map.setPaintProperty("geojsonLayer", "fill-color", [
  218. "match",
  219. ["get", "name"],
  220. ...rankingFormatted.reduce((acc, data) => {
  221. return [
  222. ...acc,
  223. data.cityName,
  224. getColor2(data[propertiesSelect], parseInt(value)),
  225. ];
  226. }, []),
  227. "#000000", // 默认颜色
  228. ]);
  229. bindMapInteractions(value);
  230. }
  231. // 设置颜色范围
  232. // const colorRange = ['#ADD8E6','#00008B'];
  233. const colorRange = ["#DBEEF6", "#36869A"];
  234. const colorRangeMin = ["#E2F0D9", "#385723"];
  235. const innovation = ["#fff4f8", "#dc7d61"];
  236. const operation = ["#e0e5e9", "#73a9d7"];
  237. const green = ["#e9f0e8", "#80c67d"];
  238. const share = ["#fff8eb", "#f6bb81"];
  239. const open = ["#eaebff", "#b67ebd"];
  240. // 创建颜色插值函数(综合得分)
  241. const colorInterpolate = chroma.scale(colorRange).domain([37, 90]);
  242. // 创建颜色插值函数(单指标得分)
  243. const colorInterpolateMin = chroma.scale(colorRangeMin).domain([1.5, 20]);
  244. const colorInnovation = chroma.scale(innovation).domain([4.1, 17.4]);
  245. const colorOperation = chroma.scale(operation).domain([9.4, 18.7]);
  246. const colorGreen = chroma.scale(green).domain([9.2, 18]);
  247. const colorOpen = chroma.scale(open).domain([1.6, 20]);
  248. const colorShare = chroma.scale(share).domain([7.5, 20]);
  249. // 根据城市值获取对应颜色
  250. function getColor2(value, type) {
  251. if (value > 20) {
  252. return colorInterpolate(value).hex();
  253. } else {
  254. switch (type) {
  255. case 0:
  256. return colorInnovation(value).hex();
  257. case 1:
  258. return colorOperation(value).hex();
  259. case 2:
  260. return colorGreen(value).hex();
  261. case 3:
  262. return colorShare(value).hex();
  263. case 4:
  264. return colorOpen(value).hex();
  265. default:
  266. break;
  267. }
  268. // return colorInterpolateMin(value).hex();
  269. }
  270. }
  271. // 悬浮地图上时,获取该城市的值
  272. function getCityValue(cityName, value) {
  273. const cityData = rankingFormatted.find((data) => data.cityName === cityName);
  274. switch (parseInt(value)) {
  275. case 0:
  276. return cityData ? cityData["创新发展"] : "N/A";
  277. case 1:
  278. return cityData ? cityData["协调发展"] : "N/A";
  279. case 2:
  280. return cityData ? cityData["绿色发展"] : "N/A";
  281. case 3:
  282. return cityData ? cityData["开放发展"] : "N/A";
  283. case 4:
  284. return cityData ? cityData["共享发展"] : "N/A";
  285. case 5:
  286. return cityData ? cityData.score : "N/A";
  287. default:
  288. return cityData ? cityData.score : "N/A";
  289. }
  290. }
  291. // 在鼠标移动到地图上显示信息
  292. let popup = null;
  293. function showPopup(e, value) {
  294. const features = e.features;
  295. if (features.length > 0) {
  296. map.getCanvas().style.cursor = "pointer";
  297. const cityName = features[0].properties.name; // 城市名称
  298. const cityValue = getCityValue(cityName, value); // 获取对应的值
  299. if (popup) {
  300. popup.remove();
  301. }
  302. // 在页面上显示浮动信息
  303. popup = new mapboxgl.Popup()
  304. .setLngLat(e.lngLat)
  305. .setHTML(`${cityName}
    评分为: ${cityValue}`
    )
  306. .addTo(map);
  307. } else {
  308. map.getCanvas().style.cursor = "";
  309. }
  310. }
  311. // 在鼠标移出时移除浮动信息
  312. function removePopup() {
  313. if (popup) {
  314. popup.remove();
  315. }
  316. map.getCanvas().style.cursor = "";
  317. }
  318. // 绑定地图交互事件,鼠标悬浮和移出事件
  319. function bindMapInteractions(value) {
  320. map.off("mousemove", "geojsonLayer", showPopup);
  321. map.on("mousemove", "geojsonLayer", (e) => showPopup(e, value));
  322. map.off("mouseout", "geojsonLayer", removePopup);
  323. map.on("mouseout", "geojsonLayer", removePopup);
  324. }

四、总结

        Mapbox的中国分部好像在2021年左右就退出中国了,官方文档的汉化工作也戛然而止,相关的社区建设也相当欠缺,内容比较混乱,最离谱的是mapbox官方底图库中的中国地图基本都是错的,天地图引入又麻烦......

        恰好我最近有一个基础的mapbox应用需求,就做了一些整理和探索,分享给大家。

        更多前端好文:各种前端问题的技巧和解决方案

        博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

文章知识点与官方知识档案匹配,可进一步学习相关知识
Vue入门技能树首页概览43124 人正在系统学习中
注:本文转载自blog.csdn.net的Watermelo617的文章"https://blog.csdn.net/RenGJ010617/article/details/137978979"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top