1. 引言

空间运算利用几何函数来接收输入的空间数据,对其进行分析,然后生成输出数据,输出数据为针对输入数据执行分析的派生结果。

可从空间运算中获得的派生数据包括:

  • 作为输入要素周围缓冲区的面
  • 作为对几何集合执行分析的结果的单个要素
  • 作为比较结果以确定不与其他要素位于同一物理空间的要素部分的单个要素
  • 作为比较结果以查找与其他要素的物理空间相交的要素部分的单个要素
  • 由彼此不位于同一物理空间的输入要素部分组成的多部分 (multipart) 要素
  • 作为两个几何的并集的要素

参考文档:空间运算—ArcMap | 文档 (arcgis.com)

JTS (Java Topology Suite) Java拓扑套件,是Java的处理地理数据的API。JTS支持一套完整的二元谓词操作。二元谓词方法将两个几何图形作为参数,返回一个布尔值来表示几何图形是否有指定的空间关系。它支持的空间关系有:相等(equals)、分离(disjoint)、相交(intersect)、相接(touches)、交叉(crosses)、包含于(within)、包含(contains)、覆盖/覆盖于(overlaps)

JTS的Github地址为:locationtech/jts: The JTS Topology Suite is a Java library for creating and manipulating vector geometry. (github.com)

JSTS是JTS的JavaScript版,并且对OpenLayers很友好

JSTS的Github地址为:bjornharrtell/jsts: JavaScript Topology Suite (github.com)

OpenLayers与JSTS集成的官方示例:JSTS Integration (openlayers.org)

本文参考OpenLayers与JSTS集成的官方示例,使用示例数据和原生JavaScript,进行求交运算和缓冲区运算,并进行可视化

2. 代码实现

2.1 引入CDN

使用JSTS、OpenLayers、jQuery的在线CDN引入

    <!-- openlayers cdn -->
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.14.1/build/ol.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.14.1/css/ol.css"> <!-- JSTS cdn -->
<script src="https://unpkg.com/jsts@2.3.0/dist/jsts.min.js"></script>
<!-- jQuery cdn -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>

2.2 页面初始化

构建HTML初始页面,新建一个地图容器,设置一些简单的CSS样式

<!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.0">
<title>Document</title>
<!-- openlayers cdn -->
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.14.1/build/ol.js"></script>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.14.1/css/ol.css"> <!-- JSTS cdn -->
<script src="https://unpkg.com/jsts@2.3.0/dist/jsts.min.js"></script>
<!-- jQuery cdn -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<style>
html,
body,
#map {
height: 100%;
}
</style>
</head> <body>
<div id="map"></div> </body> </html>

2.3 Buffer操作

Buffer操作参考OpenLayers与JSTS集成的官方示例:JSTS Integration (openlayers.org),实现代码如下:

        const linesSource = new ol.source.Vector();
$.ajax({
url: 'https://openlayers.org/en/latest/examples/data/geojson/roads-seoul.geojson',
dataType: 'json',
success: function (data) {
// console.log(data)
var features = new ol.format.GeoJSON().readFeatures(data, {
featureProjection: 'EPSG:3857'
}); const parser = new jsts.io.OL3Parser();
parser.inject(
ol.geom.Point,
ol.geom.LineString,
ol.geom.LinearRing,
ol.geom.Polygon,
ol.geom.MultiPoint,
ol.geom.MultiLineString,
ol.geom.MultiPolygon
); for (let i = 0; i < features.length; i++) {
const feature = features[i];
// convert the OpenLayers geometry to a JSTS geometry
const jstsGeom = parser.read(feature.getGeometry()); // create a buffer of 40 meters around each line
const buffered = jstsGeom.buffer(10); // convert back from JSTS and replace the geometry on the feature
feature.setGeometry(parser.write(buffered));
} linesSource.addFeatures(features)
var linesVector = new ol.layer.Vector({
source: linesSource,
}); // map.addLayer(vector); var map = new ol.Map({
target: 'map',
layers: [
// new ol.layer.Tile({
// source: new ol.source.OSM()
// }),
linesVector,
],
view: new ol.View({
center: ol.proj.fromLonLat([126.979293, 37.528787]),
zoom: 15
})
});
}
})

2.4 相交运算

相交运算(intersection)的主要代码如下,具体见下一小结的全部代码:

for (let index = 0; index < jstsgeoarr.length; index++) {
for (let index2 = index + 1; index2 < jstsgeoarr.length; index2++) {
if (jstsgeoarr[index].intersection(jstsgeoarr[index2]).toText() != 'LINESTRING EMPTY') {
point = jstsgeoarr[index].intersection(jstsgeoarr[index2])
jstsPoints.push(point)
}
}
}

2.5 结果可视化

将相交运算与缓冲区操作结合在一起使用OpenLayers进行可视化,全部代码如下:

<!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.0">
<title>Document</title>
<!-- openlayers cdn -->
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.14.1/build/ol.js"></script>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.14.1/css/ol.css"> <!-- JSTS cdn -->
<script src="https://unpkg.com/jsts@2.3.0/dist/jsts.min.js"></script>
<!-- jQuery cdn -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<style>
html,
body,
#map {
height: 100%;
}
</style>
</head> <body>
<div id="map"></div> <script>
const pointsSource = new ol.source.Vector();
const linesSource = new ol.source.Vector();
var jstsgeoarr = [];
var jstsPoints = [];
$.ajax({
url: 'https://openlayers.org/en/latest/examples/data/geojson/roads-seoul.geojson',
dataType: 'json',
success: function (data) {
// console.log(data)
var features = new ol.format.GeoJSON().readFeatures(data, {
featureProjection: 'EPSG:3857'
});
const parser = new jsts.io.OL3Parser();
parser.inject(
ol.geom.Point,
ol.geom.LineString,
ol.geom.LinearRing,
ol.geom.Polygon,
ol.geom.MultiPoint,
ol.geom.MultiLineString,
ol.geom.MultiPolygon
); for (let i = 0; i < features.length; i++) {
const feature = features[i];
// convert the OpenLayers geometry to a JSTS geometry
const jstsGeom = parser.read(feature.getGeometry()); // create a buffer of 40 meters around each line
const buffered = jstsGeom.buffer(10);
// const length = jstsGeom.length(); jstsgeoarr.push(jstsGeom) // convert back from JSTS and replace the geometry on the feature
feature.setGeometry(parser.write(buffered));
} for (let index = 0; index < jstsgeoarr.length; index++) {
for (let index2 = index + 1; index2 < jstsgeoarr.length; index2++) {
if (jstsgeoarr[index].intersection(jstsgeoarr[index2]).toText() != 'LINESTRING EMPTY') {
point = jstsgeoarr[index].intersection(jstsgeoarr[index2])
jstsPoints.push(point)
}
}
}
var intersectionfeatures = [];
for (let i = 0; i < jstsPoints.length; i++) {
const jstsPoint = jstsPoints[i];
const buffered = jstsPoint.buffer(40);
intersectionfeature = new ol.format.WKT().readFeatures(buffered.toText());
pointsSource.addFeatures(intersectionfeature)
} linesSource.addFeatures(features) var linesVector = new ol.layer.Vector({
source: linesSource,
});
var pointsVector = new ol.layer.Vector({
source: pointsSource,
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#ff0000',
width: 2
})
})
});
// map.addLayer(vector); var map = new ol.Map({
target: 'map',
layers: [
// new ol.layer.Tile({
// source: new ol.source.OSM()
// }),
linesVector,
pointsVector
],
view: new ol.View({
center: ol.proj.fromLonLat([126.979293, 37.528787]),
zoom: 15
})
});
}
}); </script>
</body> </html>

最后在浏览器查看:

3. 参考资料

[1]空间运算—ArcMap | 文档 (arcgis.com)

[2]JTS Java空间几何计算、距离、最近点、subLine等 稳健的一比,持续更新中_lakernote的博客-CSDN博客_java jts

[3]JSTS Integration (openlayers.org)

[4]GIS算法:8_JavaScript拓扑套件turf - 知乎 (zhihu.com)

[5]JTS基本概念和使用_runing9的博客-CSDN博客_jts

[6]OpenLayers v6.14.1 API - Class: WKT

[7]OpenLayers结合JSTS实现空间扩展 - 朱凤丽 (zhufengli.com)

[8]JTS Java空间几何计算、距离、最近点、subLine等 稳健的一比,持续更新中_lakernote的博客-CSDN博客_java jts

[9]JSTS demonstration (bjornharrtell.github.io)

最新文章

  1. 优化 UltraEdit 打开大文件时的性能
  2. nyoj325 zb的生日(DFS)
  3. eclipse格式化代码末班修改
  4. BZOJ_1629_[Usaco2007_Demo]_Cow_Acrobats_(贪心)
  5. 创建虚拟桌面的代码(重启桌面进程)(使用GetThreadDesktop,CreateDesktop,SetThreadDesktop等函数)
  6. bzoj1334
  7. hdu 1166 敌兵布阵_线段树
  8. poj2245Lotto(最基础的dfs)
  9. Api 和 Spi
  10. 图像切换器(ImageSwitcer)的功能与用法
  11. 【地图功能开发系列:一】根据当前坐标点获取距离不超过N公里的门店
  12. [Swift]LeetCode667. 优美的排列 II | Beautiful Arrangement II
  13. springboot返回页面
  14. Python学习(十六)—— 数据库
  15. Web开发——HTML基础(HTML表格 &lt;table&gt;)
  16. redis 在Linux下的安装与配置
  17. 在ASP.NET MVC中使用Castle Windsor
  18. ubuntu14.04, keyboard shortcuts
  19. 中石油大学统考(大学英语B)押题笔记
  20. spark 例子倒排索引

热门文章

  1. docker入门(利用docker部署web应用)
  2. CORS与CSRF在Spring Security中的使用
  3. Relational Learning with Gated and Attentive Neighbor Aggregator for Few-Shot Knowledge Graph Completion 小样本关系学习论文解读
  4. Kubernetes(k8s)存储管理之数据卷volumes(一):volumes的引入和emptyDir数据卷
  5. SpringBoot源码2——SpringBoot x Mybatis 原理解析(如何整合,事务如何交由spring管理,mybatis如何进行数据库操作)
  6. week_1
  7. 《HelloGitHub》第 81 期
  8. 启动springboot项目报错Unable to start embedded Tomcat
  9. ssm——mybatis整理
  10. 使用IntelliJ IDEA打开一个项目步骤