1.功能说明:
鼠标绘制多边形进行查询,通过多边形范围,调用Geoserver发布的WFS服务,查询相交的地图要素,将返回结果高亮显示。
单击高亮显示的要素,显示要素的属性信息。
2.网页html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
<meta name="description" content="Draw point on terrain with mouse clicks.">
<meta name="cesium-sandcastle-labels" content="Showcases">
<title>WFS属性查询</title>
<script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript" src="Sandcastle-header.js"></script>
<script type="module" src="load-cesium-es6.js"></script>
<script src="./Build/CesiumUnminified/Cesium.js"></script>
<script>window.CESIUM_BASE_URL = "./Build/CesiumUnminified/";</script>
</head>
<body class="sandcastle-loading" data-sandcastle-bucket="bucket-requirejs.html">
<style>
@import url(bucket.css);
html,
body,
#cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
<div id="cesiumContainer" class="fullSize"></div>
<div id="loadingOverlay"><h1>Loading...</h1></div>
<div id="toolbar">
<table class="infoPanel">
<tbody>
<tr>
<td>左键单击绘制点,右击结束线矩形框绘制。</td>
</tr>
</tbody>
</table>
</div>
<div id="infowindow" style="position:absolute;top:10px;right:10px;z-index:999;background:rgb(18, 100, 138);width:200px;height:50px;font-size:13px;display:none;line-height:25px;"></div>
<script src="./code.js"> </script>
</body>
</html>
3.编写的code.js代码:
Cesium.Ion.defaultAccessToken='你的Token';
window.startup = async function (Cesium) {
'use strict';
//增加视图区
const viewer = new Cesium.Viewer("cesiumContainer", {
geocoder: false,
homeButton: true,
sceneModePicker: false,
fullscreenButton: false,
vrButton: false,
baseLayerPicker: false,
infoBox: false,
selectionIndicator: false,
animation: false,
timeline: false,
shouldAnimate: true,
navigationHelpButton: false,
navigationInstructionsInitiallyVisible: false,
terrainProvider: Cesium.createWorldTerrain(),
imageryProvider: new Cesium.UrlTemplateImageryProvider({
//url: 'http://mt0.google.cn/vt/lyrs=t,r&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}',
//url: 'https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
url: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}",
//tilingScheme : new Cesium.GeographicTilingScheme(),
credit: ''
}),
});
//绘制geojson图层样式
var geoJsonStyle = {
stroke: Cesium.Color.YELLOW,
strokeWidth: 3,
fill: Cesium.Color.YELLOW.withAlpha(0.1)
};
var geoserverUrl = 'http://127.0.0.1:8180/geoserver/NtuWrokspace';
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
);
function createPoint(worldPosition) {
const point = viewer.entities.add({
position: worldPosition,
point: {
color: Cesium.Color.RED,
pixelSize: 5,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
});
return point;
}
let drawingMode = "polygon";
function drawShape(positionData) {
let shape;
if (drawingMode === "rectangle") {
} else if (drawingMode === "polygon") {
shape = viewer.entities.add({
polygon: {
hierarchy: positionData,
material: new Cesium.ColorMaterialProperty(
Cesium.Color.RED.withAlpha(0.7)
),
},
});
}
return shape;
}
/*空间查询图层
*@method queryByPolygon
*@param polygon 空间范围
*@param typeName 图层名称
*@return null
*/
function queryByPolygon(polygon, typeName, callback){
var filter =
'<Filter xmlns="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml">';
/*filter += '<And>';*/
filter += '<Intersects>';
filter += '<PropertyName>the_geom</PropertyName>';
filter += '<gml:Polygon>';
filter += '<gml:outerBoundaryIs>';
filter += '<gml:LinearRing>';
filter += '<gml:coordinates>' + polygon + '</gml:coordinates>';
filter += '</gml:LinearRing>';
filter += '</gml:outerBoundaryIs>';
filter += '</gml:Polygon>';
filter += '</Intersects>';
/*filter += '<PropertyIsLike wildCard="*" singleChar="#" escapeChar="!">';
filter += '<PropertyName>map_num</PropertyName>';
filter += '<Literal>*201911_440114*</Literal>';
filter += '</PropertyIsLike>'; */
/*filter += '</And>';*/
filter += '</Filter>';
var urlString = geoserverUrl + '/ows';
var param = {
service: 'WFS',
version: '1.0.0',
request: 'GetFeature',
typeName: typeName,
outputFormat: 'application/json',
filter: filter
};
var geojsonUrl = urlString + getParamString(param, urlString);
$.ajax({
url: geojsonUrl,
async: true,
type:'GET',
dataType: 'json',
success(result) {
callback(result);
},
error(err) {
console.log(err);
}
})
}
function getParamString(obj, existingUrl, uppercase){
var params = [];
for (var i in obj) {
params.push(encodeURIComponent(uppercase ? i.toUpperCase() : i) + '=' + encodeURIComponent(obj[i]));
}
return ((!existingUrl || existingUrl.indexOf('?') === -1) ? '?' : '&') + params.join('&');
}
/*
* 图层空间查询回调函数
*/
function callbackLastQueryWFSService(data){
console.log('data',data);
if(data && data.features.length>0){
clearGeojsonLayer();
loadGeojsonLayer(data);
}
}
/*
* 绘制图形函数
*/
function loadGeojsonLayer(geojson){
var promise = Cesium.GeoJsonDataSource.load(geojson,geoJsonStyle);
promise.then(function(dataSource) {
viewer.dataSources.add(dataSource);
viewer.zoomTo(dataSource);
}).otherwise(function(error){
//Display any errrors encountered while loading.
window.alert(error);
});
}
/*
* 清空绘制图形函数
*/
function clearGeojsonLayer(){
viewer.dataSources.removeAll();
}
function clearMap(){
clearGeojsonLayer();
}
function getExtentByPoints(points) {
if (points) {
// 指定世界范围
let lonMin = 180;
let lonMax = -180;
let latMin = 90;
let latMax = -180;
points.forEach(function (point) {
const longitude = point[0];
const latitude = point[1];
// 计算边界
lonMin = longitude < lonMin ? longitude : lonMin;
latMin = latitude < latMin ? latitude : latMin;
lonMax = longitude > lonMax ? longitude : lonMax;
latMax = latitude > latMax ? latitude : latMax;
});
const xRange = lonMax - lonMin ? lonMax - lonMin : 1;
const yRange = latMax - latMin ? latMax - latMin : 1;
// 返回数据
return [lonMin - xRange / 10, latMin - yRange / 10, lonMax + xRange / 10, latMax + yRange / 10];
}
return [-180,-90,180,90];
}
/**
* @todo 弧度坐标转经纬度坐标
* @param {Cartographic} cartographic - 弧度坐标
* @return {Object} - {longitude: x, latitude: y, height: h} - 返回经纬度
*/
function cartographicToDegrees(cartographic) {
const result = {};
result.longitude = Cesium.Math.toDegrees(cartographic.longitude);
result.latitude = Cesium.Math.toDegrees(cartographic.latitude);
if (cartographic.height > 0) {
result.height = cartographic.height;
}
return result;
}
/**
* @todo 获取 Cartesian3 四至范围
* @param {Cartesian3} cartesian3s - 世界坐标对象
* @return {*[]}
*/
function getExtentByCartesian3(cartesian3s) {
if(cartesian3s instanceof Array && cartesian3s.length>0){
const points = [];
for (let i = 0; i < cartesian3s.length; i++) {
const cartesian3 = cartesian3s[i];
// 将 cartesian3 转为经纬度数组
const cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
const point = cartographicToDegrees(cartographic);
points.push([point.longitude,point.latitude]);
}
return getExtentByPoints(points);
}
}
let activeShapePoints = [];
let activeShape;
let floatingPoint;
//窗口事件句柄
const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
handler.setInputAction(function (event) {
const ray = viewer.camera.getPickRay(event.position);//根据鼠标点击坐标和相机坐标构建射线
const earthPosition = viewer.scene.globe.pick(ray, viewer.scene);//射线与球面求交,在地面的交点
// `earthPosition` will be undefined if our mouse is not over the globe.
if (Cesium.defined(earthPosition)) //鼠标点击在地球范围内
{
if (activeShapePoints.length === 0) {
floatingPoint = createPoint(earthPosition);
activeShapePoints.push(earthPosition);
const dynamicPositions = new Cesium.CallbackProperty(function () {
if (drawingMode === "polygon") {
return new Cesium.PolygonHierarchy(activeShapePoints);
}
return activeShapePoints;
}, false);//回调函数
activeShape = drawShape(dynamicPositions);
}
activeShapePoints.push(earthPosition);
// createPoint(earthPosition);
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);//鼠标左键
handler.setInputAction(function (event) {
if (Cesium.defined(floatingPoint)) {
const ray = viewer.camera.getPickRay(event.endPosition);
const newPosition = viewer.scene.globe.pick(ray, viewer.scene);
if (Cesium.defined(newPosition)) {
floatingPoint.position.setValue(newPosition);
activeShapePoints.pop();
activeShapePoints.push(newPosition);
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);//鼠标移动
//移除临时绘制图像.
function terminateShape() {
activeShapePoints.pop();
// drawShape(activeShapePoints);
viewer.entities.remove(floatingPoint);
viewer.entities.remove(activeShape);
floatingPoint = undefined;
activeShape = undefined;
activeShapePoints = [];
}
handler.setInputAction(function (event) {
var polygon = drawShape(activeShapePoints);
//polygon.setVisible(false);
var extent =getExtentByCartesian3(activeShapePoints);
viewer.entities.remove(polygon);
terminateShape();
drawingMode = "unknown";
if(extent && extent.length>0){
//构造polygon
polygon = '';
polygon += extent[0] + ',' + extent[1] + ' ' ;
polygon += extent[2] + ',' + extent[1] + ' ' ;
polygon += extent[2] + ',' + extent[3] + ' ' ;
polygon += extent[0] + ',' + extent[3] + ' ' ;
polygon += extent[0] + ',' + extent[1] + ' ' ;
}
console.log('polygon',polygon);
if(polygon){
queryByPolygon(polygon,'NtuWrokspace:省界_region',callbackLastQueryWFSService);
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);//鼠标右键
var highlightFace = null;
viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(movement) {
var pickedFeature = viewer.scene.pick(movement.position);
console.log('pickedFeature',pickedFeature);
if(pickedFeature){
//判断之前是否有高亮面存在
if (highlightFace) {
highlightFace.material = highlightFace.material0;
}
if(pickedFeature.id.polygon.material){
pickedFeature.id.polygon.material0 = pickedFeature.id.polygon.material;
pickedFeature.id.polygon.material = Cesium.Color.DEEPSKYBLUE.withAlpha(0.8);
highlightFace = pickedFeature.id.polygon;
console.log('properties',pickedFeature.id.properties);
//气泡窗口显示
var content =
"<div>"+
"<span>图斑编号:</span><span>"+pickedFeature.id.properties.CODE+"</span></br>"+
"<span>图斑描述::</span><span>"+pickedFeature.id.properties.NAME+"</span></br>"+
"</div>";
$("#infowindow").show();
$("#infowindow").empty();
$("#infowindow").append(content);
}
}
else{
if (highlightFace) {
highlightFace.material = highlightFace.material0;
}
$("#infowindow").hide();
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
Sandcastle.addDefaultToolbarButton("框选查询", function () {
terminateShape();
drawingMode = "polygon";
});
//Example 2: Load with basic styling options.
Sandcastle.addToolbarButton("点选查询", function () {
clearMap();
drawingMode = "unknown";
});
Sandcastle.reset = function () {
viewer.dataSources.removeAll();
//Set the camera to a US centered tilted view and switch back to moving in world coordinates.
viewer.camera.lookAt(Cesium.Cartesian3.fromDegrees(115.0, 45.0),
new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0)
);
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
};
//Sandcastle_End
Sandcastle.finishedLoading();
};
if (typeof Cesium !== 'undefined') {
window.startupCalled = true;
window.startup(Cesium).catch((error) => {
"use strict";
console.error(error);
});
}
4.效果如下:
评论(0)
您还未登录,请登录后发表或查看评论