| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
- <title>地块地图</title>
- <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/leaflet/1.9.4/leaflet.css">
- <link rel="stylesheet" href="https://unpkg.com/@geoman-io/leaflet-geoman-free@latest/dist/leaflet-geoman.css">
- <script src="https://cdn.bootcdn.net/ajax/libs/leaflet/1.9.4/leaflet.js"></script>
- <script src="https://unpkg.com/@geoman-io/leaflet-geoman-free@latest/dist/leaflet-geoman.min.js"></script>
- <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
- <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
- <style>
- html,
- body,
- #map,
- .map_box {
- width: 100%;
- height: 100%;
- margin: 0;
- padding: 0;
- }
- .btn-group {
- position: fixed;
- top: 10px;
- left: 10px;
- z-index: 999999;
- display: flex;
- flex-direction: column;
- gap: 6px;
- }
- .btn-group button {
- padding: 8px 12px;
- background: #007aff;
- color: #fff;
- border: none;
- border-radius: 6px;
- font-size: 14px;
- white-space: nowrap;
- cursor: pointer;
- }
- #clearDraw {
- background: #ff3b30;
- }
- #uploadLand {
- background: #28a745;
- display: none;
- }
- #areaInfo {
- background: #fff;
- padding: 6px 10px;
- border-radius: 6px;
- font-size: 13px;
- color: #333;
- font-weight: bold;
- box-shadow: 0 1px 3px #00000033;
- }
- .draw-area-label {
- background: #007aff;
- color: #fff;
- font-weight: bold;
- padding: 5px 10px;
- border-radius: 6px;
- font-size: 14px;
- white-space: nowrap;
- box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
- pointer-events: none;
- }
- .land-label {
- background: #ffffff;
- padding: 4px 8px;
- border-radius: 6px;
- font-size: 12px;
- color: #d32f2f;
- text-align: center;
- white-space: nowrap;
- box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
- pointer-events: none !important;
- font-weight: bold;
- border: 1px solid #eee;
- line-height: 1.4;
- display: inline-block;
- }
- /* 加载动画样式 */
- .loading-overlay {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background-color: rgba(255, 255, 255, 0.9);
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: 9999999;
- flex-direction: column;
- gap: 15px;
- }
- .loading-spinner {
- width: 40px;
- height: 40px;
- border: 4px solid #e0e0e0;
- border-top: 4px solid #007aff;
- border-radius: 50%;
- animation: spin 1s linear infinite;
- }
- .loading-text {
- font-size: 15px;
- color: #333;
- }
- @keyframes spin {
- 0% {
- transform: rotate(0deg);
- }
- 100% {
- transform: rotate(360deg);
- }
- }
- </style>
- </head>
- <body>
- <!-- 加载动画 -->
- <div class="loading-overlay" id="loadingOverlay">
- <div class="loading-spinner"></div>
- <div class="loading-text">正在加载地块数据...</div>
- </div>
- <div class="map_box">
- <div id="map"></div>
- <div class="btn-group">
- <!-- <button id="sendToMini">选中地块并回传</button> -->
- <button id="startDraw">开启打点绘图</button>
- <button id="clearDraw">清除绘图</button>
- <button id="uploadLand">✅ 上传当前绘制地块</button>
- <div id="areaInfo">绘图面积:0 亩 / 0 ㎡</div>
- </div>
- </div>
- <script>
- window.onload = function() {
- // 工具函数:获取URL参数
- function getUrlParams() {
- var params = {};
- var url = window.location.href;
- var queryStr = url.split('?')[1];
- if (!queryStr) return params;
- var queryArr = queryStr.split('&');
- for (var i = 0; i < queryArr.length; i++) {
- var item = queryArr[i];
- if (!item) continue;
- var eqIndex = item.indexOf('=');
- var key = eqIndex > -1 ? item.substring(0, eqIndex) : item;
- var val = eqIndex > -1 ? decodeURIComponent(item.substring(eqIndex + 1)) : '';
- params[key] = val;
- }
- return params;
- }
- const params = getUrlParams();
- // 🔥 接收参数
- const cbfbm = params.data || '';
- const pageType = params.type || '';
- const dsType = params.displayType || '';
- const TIANDITU_TK = '0f31ca9a7e9a0b80f5e5d53df0a02925';
- // 初始化地图(先不设置中心点,加载数据后自动定位)
- var map = L.map('map', {
- zoomControl: true,
- maxZoom: 28,
- minZoom: 1,
- zoomSnap: 0.5,
- zoomDelta: 0.5
- }).setView([30, 114], 5); // 初始小视野,加载后自动调整
- // 天地图底图
- L.tileLayer(
- `https://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${TIANDITU_TK}`, {
- maxNativeZoom: 18,
- maxZoom: 28,
- minZoom: 1
- }).addTo(map);
- L.tileLayer(
- `https://t0.tianditu.gov.cn/cia_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${TIANDITU_TK}`, {
- maxNativeZoom: 18,
- maxZoom: 28,
- minZoom: 1
- }).addTo(map);
- // 初始化绘图工具
- map.pm.setLang('zh');
- // 类型为 farmer 时隐藏绘图功能
- if (pageType === 'farmer') {
- $('#startDraw').hide();
- $('#clearDraw').hide();
- $('#areaInfo').hide();
- }
- var landLayerGroup = L.layerGroup().addTo(map);
- var currentSelectedPolygon = null;
- const SHOW_LABEL_MIN_ZOOM = 18;
- let allLandItems = [];
- let drawnPolygon = null;
- let areaLabelMarker = null;
- // 点击边线添加顶点
- function enableClickAddVertex(layer) {
- layer.off('click');
- layer.on('click', function(e) {
- if (!layer.pm.enabled()) return;
- const latlng = e.latlng;
- const latlngs = layer.getLatLngs()[0];
- let closestIndex = -1;
- let minDist = Infinity;
- for (let i = 0; i < latlngs.length - 1; i++) {
- const p1 = latlngs[i];
- const p2 = latlngs[i + 1];
- const dist = L.LineUtil.pointToSegmentDistance(
- map.latLngToContainerPoint(latlng),
- map.latLngToContainerPoint(p1),
- map.latLngToContainerPoint(p2)
- );
- if (dist < minDist) {
- minDist = dist;
- closestIndex = i + 1;
- }
- }
- if (closestIndex !== -1) {
- latlngs.splice(closestIndex, 0, latlng);
- layer.setLatLngs(latlngs);
- layer.fire('pm:edit');
- }
- });
- }
- // 计算面积(亩 + 平方米)
- function calcAreaMu(latLngs) {
- if (!latLngs || latLngs.length < 3) return { mu: 0, m2: 0 };
- let m2 = 0;
- if (L.PM && L.PM.Utils && L.PM.Utils.calculatePolygonArea) {
- m2 = L.PM.Utils.calculatePolygonArea(latLngs);
- } else {
- const R = 6378137;
- const rad = Math.PI / 180;
- for (let i = 0; i < latLngs.length; i++) {
- const p1 = latLngs[i];
- const p2 = latLngs[(i + 1) % latLngs.length];
- m2 += (p2.lng - p1.lng) * rad * (2 + Math.sin(p1.lat * rad) + Math.sin(p2.lat * rad));
- }
- m2 = Math.abs(m2 * R * R / 2);
- }
- const mu = (m2 / 666.67).toFixed(2);
- return {
- mu: mu,
- m2: m2.toFixed(2)
- };
- }
- // 打印地块信息
- function printPolygonInfo(layer) {
- if (!layer) return;
- const latlngs = layer.getLatLngs()[0];
- const { mu, m2 } = calcAreaMu(latlngs);
- console.log('====================================');
- console.log('✅ 地块点位:');
- latlngs.forEach((p, i) => console.log(`第${i+1}点:${p.lat.toFixed(8)}, ${p.lng.toFixed(8)}`));
- console.log(`✅ 面积:${mu} 亩 / ${m2} 平方米`);
- console.log('====================================');
- }
- // 更新面积标签
- function updateAreaLabel() {
- if (!drawnPolygon) return;
- let latLngs = drawnPolygon.getLatLngs()[0];
- const { mu, m2 } = calcAreaMu(latLngs);
- $('#areaInfo').text(`绘图面积:${mu} 亩 / ${m2} ㎡`);
- let center = drawnPolygon.getCenter();
- if (areaLabelMarker) map.removeLayer(areaLabelMarker);
- areaLabelMarker = L.marker(center, {
- icon: L.divIcon({
- className: 'draw-area-label',
- html: `${mu} 亩 / ${m2} ㎡`,
- iconSize: null,
- iconAnchor: [50, 50]
- })
- }).addTo(map);
- }
- // 上传绘制地块
- function uploadDrawLand() {
- if (!drawnPolygon) {
- alert("请先绘制地块!");
- return;
- }
- const latlngs = drawnPolygon.getLatLngs()[0];
- const { mu, m2 } = calcAreaMu(latlngs);
- const points = latlngs.map(p => [p.lng, p.lat]);
- const confirmUpload = confirm(`确认上传当前地块?\n\n面积:${mu} 亩 / ${m2} ㎡\n\n确认后将自动返回小程序`);
- if (!confirmUpload) {
- console.log("用户取消上传");
- return;
- }
- const postData = {
- type: "drawLandFinished",
- points: points,
- areaMu: mu,
- areaM2: m2
- };
- console.log("H5 发送给小程序:", postData);
- wx.miniProgram.postMessage({
- data: postData
- });
- wx.miniProgram.navigateBack();
- }
- // 按钮事件:开启/关闭绘图
- $('#startDraw').click(function() {
- if (map.pm.Draw.Polygon._enabled) {
- map.pm.Draw.Polygon.disable();
- $(this).text('开启打点绘图').css('background', '#007aff');
- return;
- }
- $(this).text('关闭打点绘图').css('background', '#ff3b30');
- $('#uploadLand').hide();
- map.pm.Draw.Polygon.enable({
- allowSelfIntersection: false,
- markerStyle: {
- radius: 5
- }
- });
- });
- // 清除绘图
- $('#clearDraw').click(function() {
- if (drawnPolygon) {
- map.removeLayer(drawnPolygon);
- drawnPolygon = null;
- }
- if (areaLabelMarker) {
- map.removeLayer(areaLabelMarker);
- areaLabelMarker = null;
- }
- $('#areaInfo').text('绘图面积:0 亩 / 0 ㎡');
- $('#startDraw').text('开启打点绘图').css('background', '#007aff');
- $('#uploadLand').hide();
- });
- $('#uploadLand').click(uploadDrawLand);
- // 绘图完成事件
- map.on('pm:create', function(e) {
- let layer = e.layer;
- if (drawnPolygon) map.removeLayer(drawnPolygon);
- drawnPolygon = layer;
- layer.pm.enable({
- allowAddVertex: true,
- allowDeleteVertex: true,
- markerEditable: true,
- hideMiddleMarkers: false
- });
- enableClickAddVertex(layer);
- map.pm.Draw.Polygon.disable();
- $('#startDraw').text('开启打点绘图').css('background', '#007aff');
- $('#uploadLand').show();
- updateAreaLabel();
- printPolygonInfo(layer);
- layer.on('pm:edit pm:vertexadded pm:vertexremoved', function() {
- updateAreaLabel();
- printPolygonInfo(layer);
- });
- });
- // 获取多边形中心点
- function getPolygonCenter(points) {
- let latSum = 0,
- lngSum = 0,
- len = points.length;
- points.forEach(p => {
- latSum += p[1];
- lngSum += p[0];
- });
- return [latSum / len, lngSum / len];
- }
- // 自适应缩放到所有地块
- function fitMapToAllLands(allLandPoints) {
- if (!allLandPoints.length) return;
- let bounds = [];
- allLandPoints.forEach(points => {
- points.forEach(p => bounds.push([p[1], p[0]]));
- });
- map.fitBounds(L.latLngBounds(bounds), {
- padding: [30, 30]
- });
- }
- // 更新标签显示
- function updateVisibleLabels() {
- const currentZoom = map.getZoom();
- const bounds = map.getBounds();
- allLandItems.forEach(item => {
- const {
- label,
- center
- } = item;
- if (currentZoom < SHOW_LABEL_MIN_ZOOM || !bounds.contains(center)) {
- if (landLayerGroup.hasLayer(label)) landLayerGroup.removeLayer(label);
- } else {
- if (!landLayerGroup.hasLayer(label)) landLayerGroup.addLayer(label);
- }
- });
- }
- // 加载地块数据
- function loadLandData() {
- console.log(123,dsType)
- let ctData = {}
- if(dsType === 'all'){
- ctData = {
- cbfbms: cbfbm,
- }
- }else if(dsType === 'single'){
- ctData = {
- dkbms: cbfbm,
- }
- }
- $.ajax({
- url: "http://192.168.110.235:1860/miniProgram/dk/arcgisGeojson",
- type: "GET",
- data: ctData, //
- dataType: "json",
- success: function(res) {
- // 加载完成 → 隐藏加载动画
- $('#loadingOverlay').hide();
- landLayerGroup.clearLayers();
- allLandItems = [];
- let allLandPoints = [];
- if (res.code === 200 && res.data?.features?.length) {
- res.data.features.forEach(feature => {
- let rings = feature.geometry?.rings?.[0];
- if (!rings) return;
- let points = rings.map(p => [p[1], p[0]]);
- allLandPoints.push(rings);
- let center = getPolygonCenter(rings);
- let attr = feature.attributes;
- let polygon = L.polygon(points, {
- color: '#ffaa00',
- weight: 2,
- fillColor: '#ffaa00',
- fillOpacity: 0.3,
- attributes: attr
- }).addTo(landLayerGroup);
- let text =
- `${attr.cbfmc||'地块'} | ${(attr.scmjm||0).toFixed(2)}亩 | ${attr.scmj||0}㎡`;
- let label = L.marker(center, {
- icon: L.divIcon({
- className: 'land-label',
- html: text,
- iconSize: null,
- iconAnchor: [50, 50]
- })
- });
- allLandItems.push({
- label,
- center,
- polygon
- });
- // 点击选中地块
- polygon.on('click', e => {
- landLayerGroup.eachLayer(l => {
- if (l.options?.attributes) l.setStyle({
- color: '#ffaa00',
- weight: 2,
- fillOpacity: 0.3
- });
- });
- e.target.setStyle({
- color: '#ffff00',
- weight: 4,
- fillOpacity: 0.5
- });
- currentSelectedPolygon = e.target;
- });
- });
- // 自动定位到所有地块中心
- fitMapToAllLands(allLandPoints);
- updateVisibleLabels();
- }
- },
- error: () => {
- $('#loadingOverlay').hide();
- alert("获取地块失败");
- }
- });
- }
- // 地图缩放/移动时更新标签
- map.on('zoomend moveend', updateVisibleLabels);
- // 选中地块回传给小程序
- $("#sendToMini").click(function() {
- if (!currentSelectedPolygon) return alert("请先选中地块");
- let data = {
- points: currentSelectedPolygon.getLatLngs()[0].map(i => [i.lat, i.lng]),
- attr: currentSelectedPolygon.options.attributes
- };
- console.log("提交数据:", data);
- wx.miniProgram.postMessage({
- data: {
- type: "landSelected",
- data: data
- }
- });
- alert("已回传给小程序");
- });
- // 开始加载数据
- loadLandData();
- };
- </script>
- </body>
- </html>
|