@mapgis/webclient-leaflet-plugin
Version:
495 lines (440 loc) • 18.3 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title> util/LeafletFeatureRender.js</title>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/app.min.css">
<link type="text/css" rel="stylesheet" href="styles/iframe.css">
<link type="text/css" rel="stylesheet" href="">
</head>
<body class="layout small-header">
<div id="stickyNavbarOverlay"></div>
<div class="top-nav">
<div class="inner">
<a id="hamburger" role="button" class="navbar-burger" aria-label="menu" aria-expanded="false">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
<div class="logo">
<h1> MapGIS Client for JavaScript API</h1>
</div>
<div class="menu">
<div class="navigation">
<a
class="link user-link "
href="/docs/cesium/index.html"
>
Cesium
</a>
<a
class="link user-link "
href="/docs/mapboxgl/index.html"
>
MapboxGL
</a>
<a
class="link user-link "
href="/docs/leaflet/index.html"
>
Leaflet
</a>
<a
class="link user-link "
href="/docs/openlayers/index.html"
>
OpenLayers
</a>
</div>
</div>
</div>
</div>
<div id="main">
<div
class="sidebar "
id="sidebarNav"
>
<div>
<span class="mapgis-api-document-span"><a href="index.html">API文档</a></span>
</div>
<div class="search-wrapper">
<input id="search" type="text" placeholder="搜索文档..." class="input">
</div>
<nav>
<div class="category"><div style="font-weight: bold;vertical-align: middle;padding: 0.4rem 0;" class="mapgis-menu-span"><img style="width: 20px;margin-right: 6px;vertical-align: middle;" src="./styles/m.png" alt="">视图模块</div><ul class="mapgis-sidebar-menus"><li><img style="width: 20px;margin-right: 6px;vertical-align: middle;" src="./styles/c.png" alt=""><a href="DrawControl.html">DrawControl</a><span style="display: none;"><p>绘制工具</p></span></li><li><img style="width: 20px;margin-right: 6px;vertical-align: middle;" src="./styles/c.png" alt=""><a href="MapView.html">MapView</a><span style="display: none;"><p>二维场景视图(leaflet引擎),对地图引擎进行管理,如果要对地图图层进行管理请参考[Map]{@link Map},<br/>
参考示例:
<a href='#MapView'>[初始化二维场景视图]</a>
<br>[ES5引入方式]:<br/>
Zondy.MapView() <br/>
[ES6引入方式]:<br/>
import { MapView } from '@mapgis/webclient-leaflet-plugin' <br/></p></span></li><li><img style="width: 20px;margin-right: 6px;vertical-align: middle;" src="./styles/c.png" alt=""><a href="Popup.html">Popup</a><span style="display: none;"><p>二维场景信息弹窗(leaflet引擎)
参考示例:
<a href='#MapView'>[初始化二维场景视图]</a>
[ES6引入方式]:<br/>
import { Popup } from '@mapgis/webclient-leaflet-plugin' <br/>
自定义样式说明:<br/>
zondy-popup__content 弹窗容器样式<br/>
zondy-popup__tip 弹窗对话框箭头样式<br/>
zondy-popup__header 弹窗头部样式<br/>
zondy-popup__content 弹窗主体样式<br/>
zondy-popup__footer 弹窗底部样式<br/></p></span></li><li><img style="width: 20px;margin-right: 6px;vertical-align: middle;" src="./styles/c.png" alt=""><a href="Screenshot.html">Screenshot</a><span style="display: none;"><p>屏幕打印工具</p></span></li></ul><div style="font-weight: bold;vertical-align: middle;padding: 0.4rem 0;" class="mapgis-menu-span"><img style="width: 20px;margin-right: 6px;vertical-align: middle;" src="./styles/m.png" alt="">草图编辑模块</div><ul class="mapgis-sidebar-menus"><li><img style="width: 20px;margin-right: 6px;vertical-align: middle;" src="./styles/c.png" alt=""><a href="SketchEditorLeaflet.html">SketchEditorLeaflet</a><span style="display: none;"><p>二维场景草图编辑类<br/>
<br>[ES5引入方式]:<br/>
const { SketchEditorLeaflet } = Zondy <br/>
[ES6引入方式]:<br/>
import { SketchEditorLeaflet } from "@mapgis/webclient-leaflet-plugin" <br/></p></span></li></ul><div style="font-weight: bold;vertical-align: middle;padding: 0.4rem 0;" class="mapgis-menu-span"><img style="width: 20px;margin-right: 6px;vertical-align: middle;" src="./styles/m.png" alt="">渲染器模块</div><ul class="mapgis-sidebar-menus"><li><img style="width: 20px;margin-right: 6px;vertical-align: middle;" src="./styles/c.png" alt=""><a href="Zondy.ThemeLayer.GraphThemeLayer.html">GraphThemeLayer</a><span style="display: none;"><p>统计专题图通过为每个要素绘制统计图表来反映其对应的专题值的大小。它可同时表示多个字段属性信息,在区域本身与各区域之间形成横向和纵向的对比。<br>统计专题图多用于具有相关数量特征的地图上,比如表示不同地区多年的粮食产量、GDP、人口等,不同时段客运量、地铁流量等。目前提供的统计图类型有:柱状图(Bar),折线图(Line),饼图(Pie),三维柱状图(Bar3D),点状图(Point),环状图(Ring)。</p></span></li></ul></div>
</nav>
</div>
<div class="core" id="main-content-wrapper">
<div class="content">
<header id="page-title" class="page-title">
<span class="page-title-main">类名</span>
<span class="page-title-sub">util/LeafletFeatureRender.js</span>
</header>
<section>
<article>
<pre class="prettyprint source linenums"><code>import * as L from '@mapgis/leaflet'
import { FeatureRender, GeometryType } from '@mapgis/webclient-common'
import {
convertFeature,
createGraphic,
updatePolylineMarkers,
updateMultiPolylineMarkers,
getAreaCoords
} from './convertFeatureToLeafletGraphicUtil'
import ConvertGeometryUtil from './ConvertGeometryUtil'
import ConvertSymbolUtil from './ConvertSymbolUtil'
import LeafletPlugin from './LeafletPlugin'
const toLeafletStyle = ConvertSymbolUtil.convertSymboltoLeafletStyle
class LeafletFeatureRender extends FeatureRender {
/**
* @description: 绘制要素
* @param {*} innerLayer
* @param {*} features
* @return {*}
*/
drawFeature(innerLayer, features) {
if (innerLayer) {
const { layerVisible, layerOpacity } = innerLayer
features.forEach((feature) => {
if (feature.visible) {
// 异步添加
const graphic = convertFeature(feature)
// 绑定id,leaflet内部处理了id方式,为保持逻辑一致
graphic['commonFeatureId'] = feature.id
// 设置图层id
graphic['commonLayerId'] = innerLayer.commonLayerId
// 设置图层透明度和显隐
LeafletPlugin.setGraphicVisibleOpacity(
graphic,
layerOpacity,
layerVisible
)
innerLayer.addLayer(graphic)
}
})
}
}
/**
* @description: 更新样式
* @param {Object} innerLayer
* @param {Array<Feature>} features
* @param {Array<Object>} updateDetail 要素更新细节
* @return {*}
*/
updateFeature(innerLayer, features, updateDetail) {
if (innerLayer) {
super.updateFeature(innerLayer, features, updateDetail)
features.forEach((feature, i) => {
const detail = updateDetail[i]
if (!detail || !feature) return
this._update(
innerLayer,
detail.symbolUpdated,
detail.geometryUpdated,
feature
)
})
}
}
/**
* @description: 更新几何
* @param {*} innerLayer
* @param {*} geometryUpdated
* @param {*} feature
* @return {*}
*/
_update(innerLayer, symbolUpdated, geometryUpdated, feature) {
const geometry = feature.geometry
const symbol = feature.symbol
const isGeometryUpdate = !!geometryUpdated
const isSymbolUpdate = !!symbolUpdated
let isRedraw = false
const graphic = this._getGraphicByFeatureId(innerLayer, feature.id)
// 处理要素刷新机制
const visible = feature.visible
if (!visible) {
this.clearFeature(innerLayer, [feature])
return
}
// 几何图形
if (!graphic) {
this.drawFeature(innerLayer, [feature])
return
}
// 处理切换符号的机制
if (symbolUpdated) {
const { key, oldValue, value } = symbolUpdated
if (oldValue && value && oldValue.type !== value.type) {
isRedraw = true
}
if (key === 'type') {
isRedraw = true
}
}
if (!isRedraw) {
switch (geometry.type) {
case GeometryType.point: {
if (isSymbolUpdate) {
const leafletStyle = toLeafletStyle(feature.symbol) || {}
graphic.setStyle(leafletStyle)
}
if (isGeometryUpdate) {
const latlngs = ConvertGeometryUtil.toLeafletCoords(geometry)
graphic.setLatLng(latlngs[0])
}
break
}
case GeometryType.multiPoint: {
if (isSymbolUpdate) {
const leafletStyle = toLeafletStyle(feature.symbol)
graphic.eachLayer((layer) => {
layer.setStyle(leafletStyle)
})
}
if (isGeometryUpdate) {
const latlngs = ConvertGeometryUtil.toLeafletCoords(geometry)
const keys = Object.keys(graphic._layers)
const layers = keys.map((key) => graphic._layers[key]) || []
const latlngsNum = latlngs.length
let len = layers.length
// 更新多点
if (len !== latlngsNum) {
if (len > latlngsNum) {
while (len !== latlngsNum) {
graphic.removeLayer(layers[len - 1])
len -= 1
}
let i = 0
graphic.eachLayer((layer) => {
layer.setLatLng(latlngs[i])
i += 1
})
} else {
const symbolType = feature.symbol.type
const style = toLeafletStyle(feature.symbol)
latlngs.forEach((latlng, i) => {
if (i < len) {
layers[i].setLatLng(latlng)
} else {
const marker = createGraphic(symbolType, latlng, style)
graphic.addLayer(marker)
}
})
}
} else {
let i = 0
graphic.eachLayer((layer) => {
layer.setLatLng(latlngs[i])
i += 1
})
}
}
break
}
case GeometryType.lineString: {
if (isSymbolUpdate) {
const leafletStyle = toLeafletStyle(feature.symbol)
if (graphic['__line__graphic']) {
graphic['__line__graphic'].setStyle(leafletStyle)
}
}
if (isGeometryUpdate) {
const latlngs = ConvertGeometryUtil.toLeafletCoords(geometry)
if (graphic['__line__graphic']) {
graphic['__line__graphic'].setLatLngs(latlngs)
}
}
if (symbol.marker) {
updatePolylineMarkers(feature, graphic)
}
break
}
case GeometryType.multiLineString: {
if (isSymbolUpdate) {
const leafletStyle = toLeafletStyle(feature.symbol)
if (graphic['__line__graphic']) {
graphic['__line__graphic'].setStyle(leafletStyle)
}
}
if (isGeometryUpdate) {
const latlngs = ConvertGeometryUtil.toLeafletCoords(geometry)
if (graphic['__line__graphic']) {
graphic['__line__graphic'].setLatLngs(latlngs)
}
}
if (symbol.marker) {
updateMultiPolylineMarkers(feature, graphic)
}
break
}
case GeometryType.multiPolygon:
case GeometryType.polygon: {
if (isSymbolUpdate) {
const leafletStyle = toLeafletStyle(feature.symbol)
graphic.setStyle(leafletStyle)
}
if (isGeometryUpdate) {
const latlngs = getAreaCoords(symbol.type, geometry, feature)
if (graphic.setLatLngs) {
graphic.setLatLngs(latlngs)
} else if (graphic.setLatLng) {
graphic.setLatLng(latlngs)
}
}
break
}
case GeometryType.extent: {
if (isSymbolUpdate) {
const leafletStyle = toLeafletStyle(feature.symbol)
graphic.setStyle(leafletStyle)
}
if (isGeometryUpdate) {
const latlngs = getAreaCoords(symbol.type, geometry, feature)
if (graphic instanceof L.Rectangle) {
graphic.setBounds(L.latLngBounds(latlngs[0], latlngs[1]))
} else if (graphic.setLatLngs) {
graphic.setLatLngs(latlngs)
} else if (graphic.setLatLng) {
graphic.setLatLng(latlngs)
}
}
break
}
case GeometryType.circle: {
if (isSymbolUpdate) {
const leafletStyle = toLeafletStyle(feature.symbol)
graphic.setStyle(leafletStyle)
}
if (isGeometryUpdate) {
const latlngs = getAreaCoords(
symbol.type,
geometry.toPolygon(),
feature
)
if (graphic.setLatLngs) {
graphic.setLatLngs(latlngs)
} else if (graphic.setLatLng) {
graphic.setLatLng(latlngs)
}
}
break
}
default: {
break
}
}
}
// 重新绘制
if (isRedraw) {
this._redrawFeature(innerLayer, feature)
}
}
/**
* @description: 清除要素
* @param {*} innerLayer
* @param {*} features
* @return {*}
*/
clearFeature(innerLayer, features) {
if (innerLayer) {
super.clearFeature(innerLayer, features)
features.forEach((feature) => {
const _graphic = this._getGraphicByFeatureId(innerLayer, feature.id)
if (_graphic) {
innerLayer.removeLayer(_graphic)
}
})
}
}
/**
* @description: 清空上下文图层
* @param {*} innerLayer
* @return {*}
*/
clear(innerLayer) {
if (innerLayer) {
super.clear(innerLayer)
innerLayer.clearLayers()
}
}
/**
* @description: 根据要素id获取引擎图元对象
* @param {String} featureId
* @return {Object}
*/
_getGraphicByFeatureId(innerLayer, featureId) {
let _graphic = null
if (innerLayer && featureId) {
innerLayer.eachLayer((graphic) => {
if (graphic['commonFeatureId'] === featureId) {
_graphic = graphic
return _graphic
}
})
}
return _graphic
}
_redrawFeature(innerLayer, feature) {
// 类型不一致,重绘
this.clearFeature(innerLayer, [feature])
this.drawFeature(innerLayer, [feature])
}
}
export default LeafletFeatureRender
</code></pre>
</article>
</section>
</div>
<footer class="footer">
<div class="content has-text-centered">
<p>文档生成<a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.11</a></p>
<p class="sidebar-created-by">
<a href="http://www.smaryun.com" target="_blank">司马云</a> <span>© 2023 云生态圈</span>
<a href="http://192.168.82.89:8086/#/index" target="_blank">MapGIS Client for JavaScript</a>
</p>
</div>
</footer>
</div>
<div id="side-nav" class="side-nav">
<div style="margin-bottom: 10px;">
<img style="vertical-align: middle;margin-right: 10px;width: 30px;" src="./styles/anchor.png"/><a href="#page-title">构造函数</a>
</div>
<div style="margin-bottom: 10px;">
<img style="vertical-align: middle;margin-right: 10px;width: 30px;" src="./styles/anchor.png"/><a href="#member">成员变量</a>
</div>
<div style="margin-bottom: 10px;">
<img style="vertical-align: middle;margin-right: 10px;width: 30px;" src="./styles/anchor.png"/><a href="#function">方法</a>
</div>
<div>
<img style="vertical-align: middle;margin-right: 10px;width: 30px;" src="./styles/anchor.png"/><a href="#event">事件</a>
</div>
</div>
</div>
<script src="scripts/linenumber.js"> </script>
<script src="scripts/search.js"> </script>
</body>
</html>