diff --git a/src/assets/icons/icon-poi.png b/src/assets/icons/icon-poi.png new file mode 100644 index 0000000..364f2f6 --- /dev/null +++ b/src/assets/icons/icon-poi.png Binary files differ diff --git a/src/assets/icons/icon-poi.png b/src/assets/icons/icon-poi.png new file mode 100644 index 0000000..364f2f6 --- /dev/null +++ b/src/assets/icons/icon-poi.png Binary files differ diff --git a/src/components/Map/leafletMap.vue b/src/components/Map/leafletMap.vue index 9eabad8..e1150e9 100644 --- a/src/components/Map/leafletMap.vue +++ b/src/components/Map/leafletMap.vue @@ -11,7 +11,7 @@ 事件定位 部件定位 - 兴趣点属性 + @@ -39,6 +39,8 @@ import L from 'leaflet' import 'leaflet/dist/leaflet.css' import { mapGetters } from 'vuex' +import { merchantListPage } from '@/api/geoCoding/geoCoding' + const esri = require('esri-leaflet') const icon = L.icon({ @@ -48,6 +50,13 @@ popupAnchor: [0, -32] }) +const poiIcon = L.icon({ + iconUrl: require('@/assets/icons/icon-poi.png'), + iconSize: [16, 16], + iconAnchor: [8, 16], + popupAnchor: [0, -16] +}) + const deltaLng10 = 0.00002536 // 10米范围经度值偏移量(大约) const deltaLat10 = 0.00002256 // 10米范围纬度值偏移量(大约) @@ -57,7 +66,8 @@ return { map: null, baseLayer: [], - markers: [], + markers: [], // 选点 + pois: [], // 兴趣点结果 layers: { bjPoint: '', // 部件点图层 grid: '', // 单元网格图层 @@ -74,6 +84,7 @@ }, // 主页面返回值 showpoi: true, keywords: '', // 查询关键字 + limit: 100, // 兴趣点查询的最大结果数 showEventPointPopup: true, // 是否显示事部件的popup queryEventSwitch: '1', // 1==查询事件;0==查询部件 compListOpts: [] // 部件选择下拉框option @@ -121,6 +132,13 @@ that.markers.push(pos) that.map.addLayer(pos) + // 飞到定位点 + let zoom = that.map.getZoom() + if (zoom < 18) { + zoom = 18 + } + that.map.flyTo(e.latlng, zoom) + // 查询所点的网格 const query = that.layers.grid.query() query.nearby(e.latlng, 10) @@ -220,12 +238,6 @@ url: `${this.baseUrl}${this.partsAllUrl}`, minZoom: 19 }) - - // 加载网格图层 - this.layers.grid = esri.featureLayer({ - url: `${this.baseUrl}${this.gridUrl}` - }) - this.map.addLayer(this.layers.grid) }, switchEventOrComponent: function() { // 如果选中的是事件定位(1)或部件定位(0),点击地图时弹出事件或者部件的popup;否则(2以上)显示兴趣点结果的属性popup @@ -246,9 +258,40 @@ this.markers.forEach(marker => { that.map.removeLayer(marker) }) + this.pois.forEach(marker => { + that.map.removeLayer(marker) + }) }, queryOnMap: function() { - + const that = this + merchantListPage({ + keyword: this.keywords, + limit: this.limit + }).then(response => { + if (response.code === 200) { + console.log(response) + this.clearMap() + const data = response.data + if (data.total === 0) { + this.$message.warning('未找到 "' + that.keywords + '" 的兴趣点,请重新查询') + } else if (data.total > that.limit) { + this.$message.warning('"' + that.keywords + '" 的兴趣点结果过多,请重新查询') + } else { + data.rows.forEach(item => { + const popupStr = '' + const poi = L.marker([item.pointY, item.pointX], { icon: poiIcon }) + poi.bindPopup(popupStr).openPopup() + that.pois.push(poi) + that.map.addLayer(poi) + }) + } + } + }) }, // 返回事件定位的结果 checkEventPoint: function() { diff --git a/src/assets/icons/icon-poi.png b/src/assets/icons/icon-poi.png new file mode 100644 index 0000000..364f2f6 --- /dev/null +++ b/src/assets/icons/icon-poi.png Binary files differ diff --git a/src/components/Map/leafletMap.vue b/src/components/Map/leafletMap.vue index 9eabad8..e1150e9 100644 --- a/src/components/Map/leafletMap.vue +++ b/src/components/Map/leafletMap.vue @@ -11,7 +11,7 @@ 事件定位 部件定位 - 兴趣点属性 + @@ -39,6 +39,8 @@ import L from 'leaflet' import 'leaflet/dist/leaflet.css' import { mapGetters } from 'vuex' +import { merchantListPage } from '@/api/geoCoding/geoCoding' + const esri = require('esri-leaflet') const icon = L.icon({ @@ -48,6 +50,13 @@ popupAnchor: [0, -32] }) +const poiIcon = L.icon({ + iconUrl: require('@/assets/icons/icon-poi.png'), + iconSize: [16, 16], + iconAnchor: [8, 16], + popupAnchor: [0, -16] +}) + const deltaLng10 = 0.00002536 // 10米范围经度值偏移量(大约) const deltaLat10 = 0.00002256 // 10米范围纬度值偏移量(大约) @@ -57,7 +66,8 @@ return { map: null, baseLayer: [], - markers: [], + markers: [], // 选点 + pois: [], // 兴趣点结果 layers: { bjPoint: '', // 部件点图层 grid: '', // 单元网格图层 @@ -74,6 +84,7 @@ }, // 主页面返回值 showpoi: true, keywords: '', // 查询关键字 + limit: 100, // 兴趣点查询的最大结果数 showEventPointPopup: true, // 是否显示事部件的popup queryEventSwitch: '1', // 1==查询事件;0==查询部件 compListOpts: [] // 部件选择下拉框option @@ -121,6 +132,13 @@ that.markers.push(pos) that.map.addLayer(pos) + // 飞到定位点 + let zoom = that.map.getZoom() + if (zoom < 18) { + zoom = 18 + } + that.map.flyTo(e.latlng, zoom) + // 查询所点的网格 const query = that.layers.grid.query() query.nearby(e.latlng, 10) @@ -220,12 +238,6 @@ url: `${this.baseUrl}${this.partsAllUrl}`, minZoom: 19 }) - - // 加载网格图层 - this.layers.grid = esri.featureLayer({ - url: `${this.baseUrl}${this.gridUrl}` - }) - this.map.addLayer(this.layers.grid) }, switchEventOrComponent: function() { // 如果选中的是事件定位(1)或部件定位(0),点击地图时弹出事件或者部件的popup;否则(2以上)显示兴趣点结果的属性popup @@ -246,9 +258,40 @@ this.markers.forEach(marker => { that.map.removeLayer(marker) }) + this.pois.forEach(marker => { + that.map.removeLayer(marker) + }) }, queryOnMap: function() { - + const that = this + merchantListPage({ + keyword: this.keywords, + limit: this.limit + }).then(response => { + if (response.code === 200) { + console.log(response) + this.clearMap() + const data = response.data + if (data.total === 0) { + this.$message.warning('未找到 "' + that.keywords + '" 的兴趣点,请重新查询') + } else if (data.total > that.limit) { + this.$message.warning('"' + that.keywords + '" 的兴趣点结果过多,请重新查询') + } else { + data.rows.forEach(item => { + const popupStr = '' + const poi = L.marker([item.pointY, item.pointX], { icon: poiIcon }) + poi.bindPopup(popupStr).openPopup() + that.pois.push(poi) + that.map.addLayer(poi) + }) + } + } + }) }, // 返回事件定位的结果 checkEventPoint: function() { diff --git a/src/views/baseSource/components/layerChoose.vue b/src/views/baseSource/components/layerChoose.vue index c98e787..2cd75c8 100644 --- a/src/views/baseSource/components/layerChoose.vue +++ b/src/views/baseSource/components/layerChoose.vue @@ -13,11 +13,13 @@
@@ -65,6 +67,9 @@ } }, methods: { + nodeCheck(node, checked) { + this.$emit('check', node, checked) + }, checkChange(node, checked) { this.$emit('choose', node, checked) } diff --git a/src/assets/icons/icon-poi.png b/src/assets/icons/icon-poi.png new file mode 100644 index 0000000..364f2f6 --- /dev/null +++ b/src/assets/icons/icon-poi.png Binary files differ diff --git a/src/components/Map/leafletMap.vue b/src/components/Map/leafletMap.vue index 9eabad8..e1150e9 100644 --- a/src/components/Map/leafletMap.vue +++ b/src/components/Map/leafletMap.vue @@ -11,7 +11,7 @@ 事件定位 部件定位 - 兴趣点属性 + @@ -39,6 +39,8 @@ import L from 'leaflet' import 'leaflet/dist/leaflet.css' import { mapGetters } from 'vuex' +import { merchantListPage } from '@/api/geoCoding/geoCoding' + const esri = require('esri-leaflet') const icon = L.icon({ @@ -48,6 +50,13 @@ popupAnchor: [0, -32] }) +const poiIcon = L.icon({ + iconUrl: require('@/assets/icons/icon-poi.png'), + iconSize: [16, 16], + iconAnchor: [8, 16], + popupAnchor: [0, -16] +}) + const deltaLng10 = 0.00002536 // 10米范围经度值偏移量(大约) const deltaLat10 = 0.00002256 // 10米范围纬度值偏移量(大约) @@ -57,7 +66,8 @@ return { map: null, baseLayer: [], - markers: [], + markers: [], // 选点 + pois: [], // 兴趣点结果 layers: { bjPoint: '', // 部件点图层 grid: '', // 单元网格图层 @@ -74,6 +84,7 @@ }, // 主页面返回值 showpoi: true, keywords: '', // 查询关键字 + limit: 100, // 兴趣点查询的最大结果数 showEventPointPopup: true, // 是否显示事部件的popup queryEventSwitch: '1', // 1==查询事件;0==查询部件 compListOpts: [] // 部件选择下拉框option @@ -121,6 +132,13 @@ that.markers.push(pos) that.map.addLayer(pos) + // 飞到定位点 + let zoom = that.map.getZoom() + if (zoom < 18) { + zoom = 18 + } + that.map.flyTo(e.latlng, zoom) + // 查询所点的网格 const query = that.layers.grid.query() query.nearby(e.latlng, 10) @@ -220,12 +238,6 @@ url: `${this.baseUrl}${this.partsAllUrl}`, minZoom: 19 }) - - // 加载网格图层 - this.layers.grid = esri.featureLayer({ - url: `${this.baseUrl}${this.gridUrl}` - }) - this.map.addLayer(this.layers.grid) }, switchEventOrComponent: function() { // 如果选中的是事件定位(1)或部件定位(0),点击地图时弹出事件或者部件的popup;否则(2以上)显示兴趣点结果的属性popup @@ -246,9 +258,40 @@ this.markers.forEach(marker => { that.map.removeLayer(marker) }) + this.pois.forEach(marker => { + that.map.removeLayer(marker) + }) }, queryOnMap: function() { - + const that = this + merchantListPage({ + keyword: this.keywords, + limit: this.limit + }).then(response => { + if (response.code === 200) { + console.log(response) + this.clearMap() + const data = response.data + if (data.total === 0) { + this.$message.warning('未找到 "' + that.keywords + '" 的兴趣点,请重新查询') + } else if (data.total > that.limit) { + this.$message.warning('"' + that.keywords + '" 的兴趣点结果过多,请重新查询') + } else { + data.rows.forEach(item => { + const popupStr = '' + const poi = L.marker([item.pointY, item.pointX], { icon: poiIcon }) + poi.bindPopup(popupStr).openPopup() + that.pois.push(poi) + that.map.addLayer(poi) + }) + } + } + }) }, // 返回事件定位的结果 checkEventPoint: function() { diff --git a/src/views/baseSource/components/layerChoose.vue b/src/views/baseSource/components/layerChoose.vue index c98e787..2cd75c8 100644 --- a/src/views/baseSource/components/layerChoose.vue +++ b/src/views/baseSource/components/layerChoose.vue @@ -13,11 +13,13 @@
@@ -65,6 +67,9 @@ } }, methods: { + nodeCheck(node, checked) { + this.$emit('check', node, checked) + }, checkChange(node, checked) { this.$emit('choose', node, checked) } diff --git a/src/views/baseSource/components/searchItem.vue b/src/views/baseSource/components/searchItem.vue index a0c73f3..e2d52ab 100644 --- a/src/views/baseSource/components/searchItem.vue +++ b/src/views/baseSource/components/searchItem.vue @@ -10,9 +10,9 @@
-
名称:
{{ data.feature.properties.小类名称 }}
-
编码:
{{ data.feature.properties.编码 }}
-
地址:
{{ data.feature.properties.编码 }}
+
名称:
{{ data.name }}
+
编码:
{{ data.code }}
+
{{ data.content.title }}:
{{ data.content.text }}
@@ -30,14 +30,9 @@ required: true } // 数据 }, - // mounted() { - // debugger - // console.log(this.data.feature) - // }, methods: { // 点击数据项 itemClick() { - console.log('点击item') this.$emit('click', this.data) } } diff --git a/src/assets/icons/icon-poi.png b/src/assets/icons/icon-poi.png new file mode 100644 index 0000000..364f2f6 --- /dev/null +++ b/src/assets/icons/icon-poi.png Binary files differ diff --git a/src/components/Map/leafletMap.vue b/src/components/Map/leafletMap.vue index 9eabad8..e1150e9 100644 --- a/src/components/Map/leafletMap.vue +++ b/src/components/Map/leafletMap.vue @@ -11,7 +11,7 @@ 事件定位 部件定位 - 兴趣点属性 + @@ -39,6 +39,8 @@ import L from 'leaflet' import 'leaflet/dist/leaflet.css' import { mapGetters } from 'vuex' +import { merchantListPage } from '@/api/geoCoding/geoCoding' + const esri = require('esri-leaflet') const icon = L.icon({ @@ -48,6 +50,13 @@ popupAnchor: [0, -32] }) +const poiIcon = L.icon({ + iconUrl: require('@/assets/icons/icon-poi.png'), + iconSize: [16, 16], + iconAnchor: [8, 16], + popupAnchor: [0, -16] +}) + const deltaLng10 = 0.00002536 // 10米范围经度值偏移量(大约) const deltaLat10 = 0.00002256 // 10米范围纬度值偏移量(大约) @@ -57,7 +66,8 @@ return { map: null, baseLayer: [], - markers: [], + markers: [], // 选点 + pois: [], // 兴趣点结果 layers: { bjPoint: '', // 部件点图层 grid: '', // 单元网格图层 @@ -74,6 +84,7 @@ }, // 主页面返回值 showpoi: true, keywords: '', // 查询关键字 + limit: 100, // 兴趣点查询的最大结果数 showEventPointPopup: true, // 是否显示事部件的popup queryEventSwitch: '1', // 1==查询事件;0==查询部件 compListOpts: [] // 部件选择下拉框option @@ -121,6 +132,13 @@ that.markers.push(pos) that.map.addLayer(pos) + // 飞到定位点 + let zoom = that.map.getZoom() + if (zoom < 18) { + zoom = 18 + } + that.map.flyTo(e.latlng, zoom) + // 查询所点的网格 const query = that.layers.grid.query() query.nearby(e.latlng, 10) @@ -220,12 +238,6 @@ url: `${this.baseUrl}${this.partsAllUrl}`, minZoom: 19 }) - - // 加载网格图层 - this.layers.grid = esri.featureLayer({ - url: `${this.baseUrl}${this.gridUrl}` - }) - this.map.addLayer(this.layers.grid) }, switchEventOrComponent: function() { // 如果选中的是事件定位(1)或部件定位(0),点击地图时弹出事件或者部件的popup;否则(2以上)显示兴趣点结果的属性popup @@ -246,9 +258,40 @@ this.markers.forEach(marker => { that.map.removeLayer(marker) }) + this.pois.forEach(marker => { + that.map.removeLayer(marker) + }) }, queryOnMap: function() { - + const that = this + merchantListPage({ + keyword: this.keywords, + limit: this.limit + }).then(response => { + if (response.code === 200) { + console.log(response) + this.clearMap() + const data = response.data + if (data.total === 0) { + this.$message.warning('未找到 "' + that.keywords + '" 的兴趣点,请重新查询') + } else if (data.total > that.limit) { + this.$message.warning('"' + that.keywords + '" 的兴趣点结果过多,请重新查询') + } else { + data.rows.forEach(item => { + const popupStr = '' + const poi = L.marker([item.pointY, item.pointX], { icon: poiIcon }) + poi.bindPopup(popupStr).openPopup() + that.pois.push(poi) + that.map.addLayer(poi) + }) + } + } + }) }, // 返回事件定位的结果 checkEventPoint: function() { diff --git a/src/views/baseSource/components/layerChoose.vue b/src/views/baseSource/components/layerChoose.vue index c98e787..2cd75c8 100644 --- a/src/views/baseSource/components/layerChoose.vue +++ b/src/views/baseSource/components/layerChoose.vue @@ -13,11 +13,13 @@
@@ -65,6 +67,9 @@ } }, methods: { + nodeCheck(node, checked) { + this.$emit('check', node, checked) + }, checkChange(node, checked) { this.$emit('choose', node, checked) } diff --git a/src/views/baseSource/components/searchItem.vue b/src/views/baseSource/components/searchItem.vue index a0c73f3..e2d52ab 100644 --- a/src/views/baseSource/components/searchItem.vue +++ b/src/views/baseSource/components/searchItem.vue @@ -10,9 +10,9 @@
-
名称:
{{ data.feature.properties.小类名称 }}
-
编码:
{{ data.feature.properties.编码 }}
-
地址:
{{ data.feature.properties.编码 }}
+
名称:
{{ data.name }}
+
编码:
{{ data.code }}
+
{{ data.content.title }}:
{{ data.content.text }}
@@ -30,14 +30,9 @@ required: true } // 数据 }, - // mounted() { - // debugger - // console.log(this.data.feature) - // }, methods: { // 点击数据项 itemClick() { - console.log('点击item') this.$emit('click', this.data) } } diff --git a/src/views/baseSource/mapSearch.vue b/src/views/baseSource/mapSearch.vue index 71147d8..5ae0c05 100644 --- a/src/views/baseSource/mapSearch.vue +++ b/src/views/baseSource/mapSearch.vue @@ -17,7 +17,7 @@ - + @@ -45,10 +45,15 @@ drawLayer: null, // 绘制图层(框选) bounds: null, // 查询区域 clearDisabled: true, // 禁用重置按钮 - layers: this.baseConfig.layers, // 所有图层 - selectLayers: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], // 选中图层 + baseLayer: [], + layers: [ + { 'id': 0, 'name': '商户', 'type': 'layer', 'domain': [35] }, + { 'id': 1, 'name': '部件', 'type': 'layer', 'domain': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45] } + ], + selectLayers: [0], // 选中图层 maps: [], // 地图图层 parts: [], // 部件图层 + layerGroups: [], // 图层组,用于控制一组内容显示或者隐藏 searchList: [], // 全部查询结果 featureCollection: [], // 选中的图层和Feature featureCollectionLength: 0, // 选中的feature个数 @@ -60,9 +65,8 @@ ...mapGetters([ 'baseUrl', 'partsUrl', - 'partsAllUrl', - 'mapUrl', - 'partsEditUrl' + 'shopUrl', + 'mapUrl' ]) }, destroyed() { @@ -89,18 +93,17 @@ } // 其他不予处理 this.searchLoading = true const results = [] // 存放查询结果列表 - // 遍历所有图层进行查询 - const partsLength = this.parts.length // 全部部件图层数量 - for (let i = 0; i < partsLength; i++) { - const part = this.parts[i] - var str = ['编码', '小类名称', '大类名称'] - var query = esri.query({ url: part.options.url }) + + // 获取是查询部件还是查询商户 + if (this.selectLayers.toString() === '0') { + // 查询商户 + const str = ['objid', 'dutyname', 'position_'] // 查询条件属性 + const query = esri.query({ url: `${this.baseUrl}${this.shopUrl}` }) let queryString = '1=1' // 默认查询语句 // 如果有关键字 if (this.keyword) { // 拼接查询语句 queryString = str.map(item => `(${item} like '%${this.keyword}%')`).join(' OR ') - console.log(queryString) } else { return } @@ -119,18 +122,98 @@ if (featuresLength > 0) { // 遍历所有查询结果,放入results for (const feature of featureCollection.features) { + const popupStr = '' + results.push({ - layer: part, - feature: feature + name: feature.properties.dutyname, + code: feature.properties.objid, + content: { + title: '地址', + text: feature.properties.position_ + }, + lng: feature.properties.x, + lat: feature.properties.y, + popupStr: popupStr }) } } - // 如果是最后一个图层 - if (i === (partsLength - 1)) { - this.searchList = results - this.searchLoading = false - } + + this.searchList = results + this.searchLoading = false }) + } else if (this.selectLayers.toString() === '1') { + // 查询部件 + // 遍历所有图层进行查询 + const partsLength = this.parts.length // 全部部件图层数量 + for (let i = 0; i < partsLength; i++) { + const part = this.parts[i] + const str = ['objid', 'xl', 'dl'] + const query = esri.query({ url: part.url }) + let queryString = '1=1' // 默认查询语句 + // 如果有关键字 + if (this.keyword) { + // 拼接查询语句 + queryString = str.map(item => `(${item} like '%${this.keyword}%')`).join(' OR ') + } else { + return + } + query.where(queryString) + // 如果有查询边界 + if (this.bounds) { + query.within(this.bounds) + } + // 执行查询 + query.run((error, featureCollection, response) => { + if (error) { + console.log(error) + return + } + const featuresLength = featureCollection.features.length + if (featuresLength > 0) { + // 遍历所有查询结果,放入results + for (const feature of featureCollection.features) { + const popupStr = '' + + results.push({ + name: feature.properties.dl + ' / ' + feature.properties.xl, + code: feature.properties.objid, + content: { + title: '权属部门', + text: feature.properties.deptname2 + }, + lng: feature.geometry.coordinates[0], + lat: feature.geometry.coordinates[1], + popupStr: popupStr + }) + } + } + // 如果是最后一个图层 + if (i === (partsLength - 1)) { + this.searchList = results + this.searchLoading = false + } + }) + } + } else { + this.searchLoading = false } }, // 清空查询 @@ -154,28 +237,16 @@ // 赋予新的查询结果 const currentMarkesLength = data.length for (let i = 0; i < currentMarkesLength; i++) { - const feature = data[i].feature - var icon = this.searchIconList[i] - const latlng = L.latLng([feature.geometry.coordinates[1], feature.geometry.coordinates[0]]) - var item = L.marker(latlng, { icon: icon, layer: data[i].layer, properties: feature.properties }).addTo(this.map) + const icon = this.searchIconList[i] + const latlng = L.latLng([data[i].lat, data[i].lng]) + const item = L.marker(latlng, { icon: icon }).addTo(this.map) item.on('click', e => { if (item.getPopup()) { item.unbindPopup() } // 绑定弹窗 - const properties = feature.properties - var str = `
-
- ${properties['小类名称']} -
-
大类:${properties['大类名称']}
-
小类:${properties['小类名称']}
-
部件编码:${properties['编码']}
-
权属单位:${properties['权属单位'] ? properties.权属单位 : '未知'}
-
详细地址:${properties['详细地址'] ? properties.详细地址 : '未知'}
-
` - var popup = L.popup().setContent(str) - item.bindPopup(popup).openPopup(e.latlng) + const popup = L.popup().setContent(data[i].popupStr) + item.bindPopup(popup).openPopup([data[i].lat, data[i].lng]) }) this.currentSearchMarkers.push(item) } @@ -186,10 +257,8 @@ }, // 点击查询列表项,将位置放在中间 clickSearchItem(item, index) { - console.log('clickItem') if (item) { - const feature = item.feature - const latlng = L.latLng([feature.geometry.coordinates[1], feature.geometry.coordinates[0]]) + const latlng = L.latLng([item.lat, item.lng]) let zoom = this.map.getZoom() if (zoom < 19) { zoom = 19 @@ -229,36 +298,18 @@ }) }, // 部件图层切换 - layerChange(node, checked) { - const selectItem = this.layers.filter(item => item.name === node.name)[0] - // 如果选中底图,选中添加,没选中移除 - if (selectItem.type === 'map') { - if (!checked) { - for (const item of this.maps) { - this.map.removeLayer(item) - } - } else { - for (const item of this.maps) { - this.map.addLayer(item) - } - } - } else if (node.type === 'layer') { // 其他图层 - if (!checked) { - for (let i = 0; i < selectItem.domain.length; i++) { - this.map.removeLayer(this.parts[selectItem.domain[i] - 1]) - } - } else { - for (let i = 0; i < selectItem.domain.length; i++) { - this.map.addLayer(this.parts[selectItem.domain[i] - 1]) - } - } - } + layerChange(node) { + this.$refs.layerRadio.$refs.layerTree.setCheckedKeys([node.id]) + this.selectLayers = [node.id] + + // 清除查询 + this.clearSearch() }, // 地图初始化 init() { const map = L.map('map', { - minZoom: 4, - maxZoom: 21, + minZoom: 14, + maxZoom: 25, center: this.baseConfig.center, zoom: this.baseConfig.zoom, zoomControl: false, @@ -268,40 +319,64 @@ map.doubleClickZoom.disable() // 禁止双击 this.map = map // data挂载map window.map = map - // 添加底图 - for (let i = 0; i <= 21; i++) { - const item = { url: `${this.baseUrl}${this.mapUrl}/${i}` } - this.maps.push(esri.featureLayer(item).addTo(map)) + + // 加载天地图底图和标注 + this.baseLayer.push(L.tileLayer(this.baseConfig.mapUrl).addTo(map)) + this.baseLayer.push(L.tileLayer(this.baseConfig.labelUrl).addTo(map)) + + // 构建并加载layerGroup + /* eslint-disable new-cap */ + this.addMapDtLyaer() // 底图 + + // 部件图层组 + for (let i = 3; i < 10; i++) { + this.addPartsLayer(i) } - // 添加部件图层 - const partsLayer = this.baseConfig.partsLayer - for (const parent of partsLayer) { // 遍历大类 - const childs = parent.children - for (const child of childs) { // 遍历小类 - const item = { url: `${this.baseUrl}${this.partsUrl}/${child.layer}`, minZoom: 18 } - console.log(item) - var layer = esri.featureLayer(item).addTo(map) - // 点击部件事件 - layer.on('click', function(e) { - // 获取要素的属性 - const properties = e.layer.feature.properties - // 弹窗样式 - var str = `
-
- ${properties['小类名称']} -
-
大类:${properties['大类名称']}
-
小类:${properties['小类名称']}
-
部件编码:${properties['编码']}
-
权属单位:${properties['权属单位'] ? properties.权属单位 : '未知'}
-
详细地址:${properties['详细地址'] ? properties.详细地址 : '未知'}
-
` - var popup = L.popup().setContent(str) - e.layer.dragging._marker.bindPopup(popup, { minWidth: 200 }).openPopup() - }) - this.parts.push(layer) - } - } + }, + // 添加底图图层 + addMapDtLyaer: function() { + const mapDtGroup = new L.layerGroup() // 创建layerGroup + + // 创建图层并加载到layerGroup中 + const item = { url: `${this.baseUrl}${this.mapUrl}` } + esri.dynamicMapLayer(item).addTo(mapDtGroup) + + this.layerGroups.push(mapDtGroup) + this.map.addLayer(mapDtGroup) + }, + addPartsLayer: function(index) { + const that = this + const group = new L.layerGroup() // 创建layerGroup + + const domains = this.baseConfig.layers[index].domain + domains.forEach(dom => { + // 创建图层并加载到layerGroup中 + const item = { url: `${this.baseUrl}${this.partsUrl}/${dom}`, minZoom: 18 } + const layer = esri.featureLayer(item).addTo(group) + this.parts.push(item) + + layer.on('click', function(e) { + // 获取要素的属性 + const properties = e.layer.feature.properties + + // 弹窗样式 + const popupStr = '' + // 弹出窗口 + L.popup().setContent(popupStr).setLatLng(e.latlng).openOn(that.map) + }) + + that.layerGroups.push(group) + }) + this.map.addLayer(group) }, // 初始化图标 initIcons() { @@ -310,23 +385,17 @@ const icon = L.icon({ iconUrl: require(`@/assets/global_images/point${i}.png`), iconSize: [25, 25], - iconAnchor: [12.5, 25] + iconAnchor: [12, 25], + popupAnchor: [0, -25] }) this.searchIconList.push(icon) } }, handleCurrentChange(val) { this.offset = val - var num = 5 * val >= this.searchlist.length ? this.searchlist.length : 5 * val - this.showlist = this.searchlist.slice(5 * (val - 1), num) + const num = 5 * val >= this.searchList.length ? this.searchList.length : 5 * val + this.showlist = this.searchList.slice(5 * (val - 1), num) this.drawIcon() - }, - // 根据url找到layer - searchLayerByUrl(url) { - const layer = this.parts.filter(item => item.options.url === url)[0] - if (layer) { - this.currentLayer = layer - } } } } @@ -345,8 +414,9 @@ /*}*/ $tableTitleHeight:35px; .leaflet_container{ - width: 100%; - height: 84vh; + width: calc( 100vw - 208px ); + height: calc( 100vh - 158px ); + background-color: white; } .search-total{ background-color: white; width: 300px;height: 35px; @@ -453,3 +523,33 @@ } } + + diff --git a/src/assets/icons/icon-poi.png b/src/assets/icons/icon-poi.png new file mode 100644 index 0000000..364f2f6 --- /dev/null +++ b/src/assets/icons/icon-poi.png Binary files differ diff --git a/src/components/Map/leafletMap.vue b/src/components/Map/leafletMap.vue index 9eabad8..e1150e9 100644 --- a/src/components/Map/leafletMap.vue +++ b/src/components/Map/leafletMap.vue @@ -11,7 +11,7 @@ 事件定位 部件定位 - 兴趣点属性 + @@ -39,6 +39,8 @@ import L from 'leaflet' import 'leaflet/dist/leaflet.css' import { mapGetters } from 'vuex' +import { merchantListPage } from '@/api/geoCoding/geoCoding' + const esri = require('esri-leaflet') const icon = L.icon({ @@ -48,6 +50,13 @@ popupAnchor: [0, -32] }) +const poiIcon = L.icon({ + iconUrl: require('@/assets/icons/icon-poi.png'), + iconSize: [16, 16], + iconAnchor: [8, 16], + popupAnchor: [0, -16] +}) + const deltaLng10 = 0.00002536 // 10米范围经度值偏移量(大约) const deltaLat10 = 0.00002256 // 10米范围纬度值偏移量(大约) @@ -57,7 +66,8 @@ return { map: null, baseLayer: [], - markers: [], + markers: [], // 选点 + pois: [], // 兴趣点结果 layers: { bjPoint: '', // 部件点图层 grid: '', // 单元网格图层 @@ -74,6 +84,7 @@ }, // 主页面返回值 showpoi: true, keywords: '', // 查询关键字 + limit: 100, // 兴趣点查询的最大结果数 showEventPointPopup: true, // 是否显示事部件的popup queryEventSwitch: '1', // 1==查询事件;0==查询部件 compListOpts: [] // 部件选择下拉框option @@ -121,6 +132,13 @@ that.markers.push(pos) that.map.addLayer(pos) + // 飞到定位点 + let zoom = that.map.getZoom() + if (zoom < 18) { + zoom = 18 + } + that.map.flyTo(e.latlng, zoom) + // 查询所点的网格 const query = that.layers.grid.query() query.nearby(e.latlng, 10) @@ -220,12 +238,6 @@ url: `${this.baseUrl}${this.partsAllUrl}`, minZoom: 19 }) - - // 加载网格图层 - this.layers.grid = esri.featureLayer({ - url: `${this.baseUrl}${this.gridUrl}` - }) - this.map.addLayer(this.layers.grid) }, switchEventOrComponent: function() { // 如果选中的是事件定位(1)或部件定位(0),点击地图时弹出事件或者部件的popup;否则(2以上)显示兴趣点结果的属性popup @@ -246,9 +258,40 @@ this.markers.forEach(marker => { that.map.removeLayer(marker) }) + this.pois.forEach(marker => { + that.map.removeLayer(marker) + }) }, queryOnMap: function() { - + const that = this + merchantListPage({ + keyword: this.keywords, + limit: this.limit + }).then(response => { + if (response.code === 200) { + console.log(response) + this.clearMap() + const data = response.data + if (data.total === 0) { + this.$message.warning('未找到 "' + that.keywords + '" 的兴趣点,请重新查询') + } else if (data.total > that.limit) { + this.$message.warning('"' + that.keywords + '" 的兴趣点结果过多,请重新查询') + } else { + data.rows.forEach(item => { + const popupStr = '' + const poi = L.marker([item.pointY, item.pointX], { icon: poiIcon }) + poi.bindPopup(popupStr).openPopup() + that.pois.push(poi) + that.map.addLayer(poi) + }) + } + } + }) }, // 返回事件定位的结果 checkEventPoint: function() { diff --git a/src/views/baseSource/components/layerChoose.vue b/src/views/baseSource/components/layerChoose.vue index c98e787..2cd75c8 100644 --- a/src/views/baseSource/components/layerChoose.vue +++ b/src/views/baseSource/components/layerChoose.vue @@ -13,11 +13,13 @@
@@ -65,6 +67,9 @@ } }, methods: { + nodeCheck(node, checked) { + this.$emit('check', node, checked) + }, checkChange(node, checked) { this.$emit('choose', node, checked) } diff --git a/src/views/baseSource/components/searchItem.vue b/src/views/baseSource/components/searchItem.vue index a0c73f3..e2d52ab 100644 --- a/src/views/baseSource/components/searchItem.vue +++ b/src/views/baseSource/components/searchItem.vue @@ -10,9 +10,9 @@
-
名称:
{{ data.feature.properties.小类名称 }}
-
编码:
{{ data.feature.properties.编码 }}
-
地址:
{{ data.feature.properties.编码 }}
+
名称:
{{ data.name }}
+
编码:
{{ data.code }}
+
{{ data.content.title }}:
{{ data.content.text }}
@@ -30,14 +30,9 @@ required: true } // 数据 }, - // mounted() { - // debugger - // console.log(this.data.feature) - // }, methods: { // 点击数据项 itemClick() { - console.log('点击item') this.$emit('click', this.data) } } diff --git a/src/views/baseSource/mapSearch.vue b/src/views/baseSource/mapSearch.vue index 71147d8..5ae0c05 100644 --- a/src/views/baseSource/mapSearch.vue +++ b/src/views/baseSource/mapSearch.vue @@ -17,7 +17,7 @@ - +
@@ -45,10 +45,15 @@ drawLayer: null, // 绘制图层(框选) bounds: null, // 查询区域 clearDisabled: true, // 禁用重置按钮 - layers: this.baseConfig.layers, // 所有图层 - selectLayers: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], // 选中图层 + baseLayer: [], + layers: [ + { 'id': 0, 'name': '商户', 'type': 'layer', 'domain': [35] }, + { 'id': 1, 'name': '部件', 'type': 'layer', 'domain': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45] } + ], + selectLayers: [0], // 选中图层 maps: [], // 地图图层 parts: [], // 部件图层 + layerGroups: [], // 图层组,用于控制一组内容显示或者隐藏 searchList: [], // 全部查询结果 featureCollection: [], // 选中的图层和Feature featureCollectionLength: 0, // 选中的feature个数 @@ -60,9 +65,8 @@ ...mapGetters([ 'baseUrl', 'partsUrl', - 'partsAllUrl', - 'mapUrl', - 'partsEditUrl' + 'shopUrl', + 'mapUrl' ]) }, destroyed() { @@ -89,18 +93,17 @@ } // 其他不予处理 this.searchLoading = true const results = [] // 存放查询结果列表 - // 遍历所有图层进行查询 - const partsLength = this.parts.length // 全部部件图层数量 - for (let i = 0; i < partsLength; i++) { - const part = this.parts[i] - var str = ['编码', '小类名称', '大类名称'] - var query = esri.query({ url: part.options.url }) + + // 获取是查询部件还是查询商户 + if (this.selectLayers.toString() === '0') { + // 查询商户 + const str = ['objid', 'dutyname', 'position_'] // 查询条件属性 + const query = esri.query({ url: `${this.baseUrl}${this.shopUrl}` }) let queryString = '1=1' // 默认查询语句 // 如果有关键字 if (this.keyword) { // 拼接查询语句 queryString = str.map(item => `(${item} like '%${this.keyword}%')`).join(' OR ') - console.log(queryString) } else { return } @@ -119,18 +122,98 @@ if (featuresLength > 0) { // 遍历所有查询结果,放入results for (const feature of featureCollection.features) { + const popupStr = '' + results.push({ - layer: part, - feature: feature + name: feature.properties.dutyname, + code: feature.properties.objid, + content: { + title: '地址', + text: feature.properties.position_ + }, + lng: feature.properties.x, + lat: feature.properties.y, + popupStr: popupStr }) } } - // 如果是最后一个图层 - if (i === (partsLength - 1)) { - this.searchList = results - this.searchLoading = false - } + + this.searchList = results + this.searchLoading = false }) + } else if (this.selectLayers.toString() === '1') { + // 查询部件 + // 遍历所有图层进行查询 + const partsLength = this.parts.length // 全部部件图层数量 + for (let i = 0; i < partsLength; i++) { + const part = this.parts[i] + const str = ['objid', 'xl', 'dl'] + const query = esri.query({ url: part.url }) + let queryString = '1=1' // 默认查询语句 + // 如果有关键字 + if (this.keyword) { + // 拼接查询语句 + queryString = str.map(item => `(${item} like '%${this.keyword}%')`).join(' OR ') + } else { + return + } + query.where(queryString) + // 如果有查询边界 + if (this.bounds) { + query.within(this.bounds) + } + // 执行查询 + query.run((error, featureCollection, response) => { + if (error) { + console.log(error) + return + } + const featuresLength = featureCollection.features.length + if (featuresLength > 0) { + // 遍历所有查询结果,放入results + for (const feature of featureCollection.features) { + const popupStr = '' + + results.push({ + name: feature.properties.dl + ' / ' + feature.properties.xl, + code: feature.properties.objid, + content: { + title: '权属部门', + text: feature.properties.deptname2 + }, + lng: feature.geometry.coordinates[0], + lat: feature.geometry.coordinates[1], + popupStr: popupStr + }) + } + } + // 如果是最后一个图层 + if (i === (partsLength - 1)) { + this.searchList = results + this.searchLoading = false + } + }) + } + } else { + this.searchLoading = false } }, // 清空查询 @@ -154,28 +237,16 @@ // 赋予新的查询结果 const currentMarkesLength = data.length for (let i = 0; i < currentMarkesLength; i++) { - const feature = data[i].feature - var icon = this.searchIconList[i] - const latlng = L.latLng([feature.geometry.coordinates[1], feature.geometry.coordinates[0]]) - var item = L.marker(latlng, { icon: icon, layer: data[i].layer, properties: feature.properties }).addTo(this.map) + const icon = this.searchIconList[i] + const latlng = L.latLng([data[i].lat, data[i].lng]) + const item = L.marker(latlng, { icon: icon }).addTo(this.map) item.on('click', e => { if (item.getPopup()) { item.unbindPopup() } // 绑定弹窗 - const properties = feature.properties - var str = `
-
- ${properties['小类名称']} -
-
大类:${properties['大类名称']}
-
小类:${properties['小类名称']}
-
部件编码:${properties['编码']}
-
权属单位:${properties['权属单位'] ? properties.权属单位 : '未知'}
-
详细地址:${properties['详细地址'] ? properties.详细地址 : '未知'}
-
` - var popup = L.popup().setContent(str) - item.bindPopup(popup).openPopup(e.latlng) + const popup = L.popup().setContent(data[i].popupStr) + item.bindPopup(popup).openPopup([data[i].lat, data[i].lng]) }) this.currentSearchMarkers.push(item) } @@ -186,10 +257,8 @@ }, // 点击查询列表项,将位置放在中间 clickSearchItem(item, index) { - console.log('clickItem') if (item) { - const feature = item.feature - const latlng = L.latLng([feature.geometry.coordinates[1], feature.geometry.coordinates[0]]) + const latlng = L.latLng([item.lat, item.lng]) let zoom = this.map.getZoom() if (zoom < 19) { zoom = 19 @@ -229,36 +298,18 @@ }) }, // 部件图层切换 - layerChange(node, checked) { - const selectItem = this.layers.filter(item => item.name === node.name)[0] - // 如果选中底图,选中添加,没选中移除 - if (selectItem.type === 'map') { - if (!checked) { - for (const item of this.maps) { - this.map.removeLayer(item) - } - } else { - for (const item of this.maps) { - this.map.addLayer(item) - } - } - } else if (node.type === 'layer') { // 其他图层 - if (!checked) { - for (let i = 0; i < selectItem.domain.length; i++) { - this.map.removeLayer(this.parts[selectItem.domain[i] - 1]) - } - } else { - for (let i = 0; i < selectItem.domain.length; i++) { - this.map.addLayer(this.parts[selectItem.domain[i] - 1]) - } - } - } + layerChange(node) { + this.$refs.layerRadio.$refs.layerTree.setCheckedKeys([node.id]) + this.selectLayers = [node.id] + + // 清除查询 + this.clearSearch() }, // 地图初始化 init() { const map = L.map('map', { - minZoom: 4, - maxZoom: 21, + minZoom: 14, + maxZoom: 25, center: this.baseConfig.center, zoom: this.baseConfig.zoom, zoomControl: false, @@ -268,40 +319,64 @@ map.doubleClickZoom.disable() // 禁止双击 this.map = map // data挂载map window.map = map - // 添加底图 - for (let i = 0; i <= 21; i++) { - const item = { url: `${this.baseUrl}${this.mapUrl}/${i}` } - this.maps.push(esri.featureLayer(item).addTo(map)) + + // 加载天地图底图和标注 + this.baseLayer.push(L.tileLayer(this.baseConfig.mapUrl).addTo(map)) + this.baseLayer.push(L.tileLayer(this.baseConfig.labelUrl).addTo(map)) + + // 构建并加载layerGroup + /* eslint-disable new-cap */ + this.addMapDtLyaer() // 底图 + + // 部件图层组 + for (let i = 3; i < 10; i++) { + this.addPartsLayer(i) } - // 添加部件图层 - const partsLayer = this.baseConfig.partsLayer - for (const parent of partsLayer) { // 遍历大类 - const childs = parent.children - for (const child of childs) { // 遍历小类 - const item = { url: `${this.baseUrl}${this.partsUrl}/${child.layer}`, minZoom: 18 } - console.log(item) - var layer = esri.featureLayer(item).addTo(map) - // 点击部件事件 - layer.on('click', function(e) { - // 获取要素的属性 - const properties = e.layer.feature.properties - // 弹窗样式 - var str = `
-
- ${properties['小类名称']} -
-
大类:${properties['大类名称']}
-
小类:${properties['小类名称']}
-
部件编码:${properties['编码']}
-
权属单位:${properties['权属单位'] ? properties.权属单位 : '未知'}
-
详细地址:${properties['详细地址'] ? properties.详细地址 : '未知'}
-
` - var popup = L.popup().setContent(str) - e.layer.dragging._marker.bindPopup(popup, { minWidth: 200 }).openPopup() - }) - this.parts.push(layer) - } - } + }, + // 添加底图图层 + addMapDtLyaer: function() { + const mapDtGroup = new L.layerGroup() // 创建layerGroup + + // 创建图层并加载到layerGroup中 + const item = { url: `${this.baseUrl}${this.mapUrl}` } + esri.dynamicMapLayer(item).addTo(mapDtGroup) + + this.layerGroups.push(mapDtGroup) + this.map.addLayer(mapDtGroup) + }, + addPartsLayer: function(index) { + const that = this + const group = new L.layerGroup() // 创建layerGroup + + const domains = this.baseConfig.layers[index].domain + domains.forEach(dom => { + // 创建图层并加载到layerGroup中 + const item = { url: `${this.baseUrl}${this.partsUrl}/${dom}`, minZoom: 18 } + const layer = esri.featureLayer(item).addTo(group) + this.parts.push(item) + + layer.on('click', function(e) { + // 获取要素的属性 + const properties = e.layer.feature.properties + + // 弹窗样式 + const popupStr = '' + // 弹出窗口 + L.popup().setContent(popupStr).setLatLng(e.latlng).openOn(that.map) + }) + + that.layerGroups.push(group) + }) + this.map.addLayer(group) }, // 初始化图标 initIcons() { @@ -310,23 +385,17 @@ const icon = L.icon({ iconUrl: require(`@/assets/global_images/point${i}.png`), iconSize: [25, 25], - iconAnchor: [12.5, 25] + iconAnchor: [12, 25], + popupAnchor: [0, -25] }) this.searchIconList.push(icon) } }, handleCurrentChange(val) { this.offset = val - var num = 5 * val >= this.searchlist.length ? this.searchlist.length : 5 * val - this.showlist = this.searchlist.slice(5 * (val - 1), num) + const num = 5 * val >= this.searchList.length ? this.searchList.length : 5 * val + this.showlist = this.searchList.slice(5 * (val - 1), num) this.drawIcon() - }, - // 根据url找到layer - searchLayerByUrl(url) { - const layer = this.parts.filter(item => item.options.url === url)[0] - if (layer) { - this.currentLayer = layer - } } } } @@ -345,8 +414,9 @@ /*}*/ $tableTitleHeight:35px; .leaflet_container{ - width: 100%; - height: 84vh; + width: calc( 100vw - 208px ); + height: calc( 100vh - 158px ); + background-color: white; } .search-total{ background-color: white; width: 300px;height: 35px; @@ -453,3 +523,33 @@ } } + + diff --git a/src/views/baseSource/overview.vue b/src/views/baseSource/overview.vue index 040f3e0..02267ef 100644 --- a/src/views/baseSource/overview.vue +++ b/src/views/baseSource/overview.vue @@ -117,9 +117,6 @@ const item = { url: `${this.baseUrl}${this.shopUrl}` } const layer = esri.featureLayer(item).addTo(shopGroup) - const shopLabel = { url: `${this.baseUrl}${this.mapUrl}/2` } - esri.featureLayer(shopLabel).addTo(shopGroup) - const that = this layer.on('click', function(e) { // 获取要素的属性 @@ -131,9 +128,10 @@ '
' + '' + '' + - '' + - '' + + // '' + + // '' + '' + + '' + '
' // 弹出窗口 L.popup().setContent(popupStr).setLatLng(e.latlng).openOn(that.map) @@ -180,7 +178,7 @@