国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java中使用JTS實(shí)現(xiàn)WKT字符串讀取轉(zhuǎn)換線、查找LineString的list中距離最近的線、LineString做緩沖區(qū)擴(kuò)展并計(jì)算點(diǎn)在緩沖區(qū)內(nèi)的方位角

這篇具有很好參考價(jià)值的文章主要介紹了Java中使用JTS實(shí)現(xiàn)WKT字符串讀取轉(zhuǎn)換線、查找LineString的list中距離最近的線、LineString做緩沖區(qū)擴(kuò)展并計(jì)算點(diǎn)在緩沖區(qū)內(nèi)的方位角。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

場景

Java中使用JTS對空間幾何計(jì)算(讀取WKT、距離、點(diǎn)在面內(nèi)、長度、面積、相交等):

Java中使用JTS對空間幾何計(jì)算(讀取WKT、距離、點(diǎn)在面內(nèi)、長度、面積、相交等)_jts-core_霸道流氓氣質(zhì)的博客-CSDN博客

Java+GeoTools實(shí)現(xiàn)WKT數(shù)據(jù)根據(jù)EPSG編碼進(jìn)行坐標(biāo)系轉(zhuǎn)換:

Java+GeoTools實(shí)現(xiàn)WKT數(shù)據(jù)根據(jù)EPSG編碼進(jìn)行坐標(biāo)系轉(zhuǎn)換_霸道流氓氣質(zhì)的博客-CSDN博客

基于gis的業(yè)務(wù)場景中,需要在地圖中錄入?yún)^(qū)域數(shù)據(jù)的wkt數(shù)據(jù),然后根據(jù)某個坐標(biāo)點(diǎn)判斷是屬于哪個區(qū)域,

以及距離所屬區(qū)域中最近的端點(diǎn)的方位角,比如坐標(biāo)點(diǎn)位于某區(qū)域東南方向100米。

注:

博客:
霸道流氓氣質(zhì)_C#,架構(gòu)之路,SpringBoot-CSDN博客

實(shí)現(xiàn)

1、參考上面引入jts的依賴。

首先數(shù)據(jù)庫中存儲的所有線的WKT數(shù)據(jù)為

Java中使用JTS實(shí)現(xiàn)WKT字符串讀取轉(zhuǎn)換線、查找LineString的list中距離最近的線、LineString做緩沖區(qū)擴(kuò)展并計(jì)算點(diǎn)在緩沖區(qū)內(nèi)的方位角,Java,java,list,python

其中region_name為線的名稱,region_wkt為線的wkt字符串。

首先從數(shù)據(jù)庫中讀取所有的wkt字符串?dāng)?shù)據(jù),并轉(zhuǎn)換為map類型數(shù)據(jù)方便處理以及賦值線的名稱到linestring的userData字段。

??????? List<LineString> regionList = new ArrayList<>();

??????? Map<String, List<LineString>> regionMap = new HashMap<>();

??????? //讀取錄入的區(qū)域位置信息
??????? RegionManagement param = RegionManagement.builder().deleteFlag(false).build();
??????? List<RegionManagement> regionManagements = regionManagementMapper.selectList(param);
??????? for (RegionManagement regionManagement : regionManagements) {
??????????? LineString lineString = readWKT(regionManagement.getRegionWKT());
??????????? RegionDTO regionDTO = JSON.parseObject(JSON.toJSONString(regionManagement), RegionDTO.class);
??????????? regionDTO.setUpdateTime(regionManagement.getUpdateTime().toString());
??????????? lineString.setUserData(regionDTO);
??????????? regionList.add(lineString);
??????? }
??????? //將區(qū)域list流處理為map,方便快速查找
??????? Map<String, List<RegionManagement>> collect = regionManagements.stream().collect(Collectors.groupingBy(RegionManagement::getRegionName));
??????? for (String name : collect.keySet()) {
??????????? List<LineString> tmp = new ArrayList<>();
??????????? collect.get(name).forEach(item -> tmp.add(readWKT(item.getRegionWKT())));
??????????? regionMap.put(name, tmp);
??????? }

這里的RegionManagement用來讀取數(shù)據(jù)庫中存儲的wkt字符串等數(shù)據(jù),實(shí)現(xiàn)為

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class RegionManagement {

??? private Long id;
??? private String regionName;
??? private String regionWKT;
??? // 0 false ; 1 true
??? private boolean deleteFlag;
??? @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
??? private Date updateTime;

}

調(diào)用讀取wkt字符串并轉(zhuǎn)換為jts的LineString對象的方法readWKT實(shí)現(xiàn)為

??? //讀取wkt數(shù)據(jù)為LineString
??? public LineString readWKT(String regionWKT){
??????? GeometryFactory fact = new GeometryFactory();
??????? WKTReader reader = new WKTReader(fact);
??????? LineString geometry1 = null;
??????? try {
??????????? geometry1 = (LineString) reader.read(regionWKT);
??????? } catch (ParseException e) {
??????????? e.printStackTrace();
??????? }
??????? return geometry1;
??? }

中間獲取所需要的數(shù)據(jù)的RegionDTO的實(shí)現(xiàn)為

import lombok.Data;

@Data
public class RegionDTO {
??? private Long id;
??? private String regionName;
??? private String updateTime;
}

2、將要判斷方位的坐標(biāo)值聲明為Point2D對象

??????? //目標(biāo)點(diǎn)位
??????? Point2D.Double carPoint = new Point2D.Double(36582834.745, 4259820.7951);

3、獲取距離目標(biāo)點(diǎn)位最近的線

??????? //獲取離目標(biāo)點(diǎn)位最近的線
??????? LineString lineString = findNearestLine(carPoint, 10D, regionList);

這里調(diào)用的findNearestLine方法的實(shí)現(xiàn)

??? //查找最近的線,jts工具做線的緩沖區(qū),擴(kuò)展寬度為10
??? public? LineString findNearestLine(java.awt.geom.Point2D.Double point, Double FuzzyLookupRange, List<LineString> lineStringList) {
??????? Point a = createPoint(point.getX(), point.getY());
??????? return lineStringList.parallelStream().filter((lineString) -> lineString.buffer(FuzzyLookupRange).contains(a)).min((o1, o2) -> {
??????????? Double ax = o1.distance(a);
??????????? Double axx = o2.distance(a);
??????????? return ax.compareTo(axx);
??????? }).orElse(null);
??? }

這里調(diào)用了createPoint用來創(chuàng)建point對象

??? //根據(jù)坐標(biāo)x y創(chuàng)建點(diǎn)對象
??? public static Point createPoint(Double x, Double y) {
??????? GeometryFactory a = JTSFactoryFinder.getGeometryFactory();
??????? return a.createPoint(new Coordinate(x, y));
??? }

然后使用lineString.buffer方法對線做緩沖區(qū),擴(kuò)展寬度為10,即將線向外擴(kuò)充成類似區(qū)域的概念,判斷點(diǎn)是否在擴(kuò)充后

的區(qū)域內(nèi),如果有多個區(qū)域,則取距離最小的一個。

LineString.buffer方法的使用可參考:

Geometry (JTS Topology Suite 1.13 API) - Javadoc Extreme)

Computes a buffer area around this geometry having the given width. The buffer of a Geometry is the Minkowski sum or difference of the geometry

with a disc of radius abs(distance).

Mathematically-exact buffer area boundaries can contain circular arcs.

To represent these arcs using linear geometry they must be approximated with line segments.

The buffer geometry is constructed using 8 segments per quadrant to approximate the circular arcs. The end cap style is CAP_ROUND.

The buffer operation always returns a polygonal result. The negative or zero-distance buffer of lines and points is always an empty Polygon.

?This is also the result for the buffers of degenerate (zero-area) polygons.

直譯:

計(jì)算具有給定寬度的幾何體周圍的緩沖區(qū)。幾何體的緩沖區(qū)是具有半徑為abs(距離)的圓盤的幾何體的Minkowski和或差。

數(shù)學(xué)上精確的緩沖區(qū)邊界可以包含圓弧。要使用線性幾何圖形表示這些圓弧,必須使用線段對其進(jìn)行近似。

緩沖區(qū)幾何結(jié)構(gòu)使用每個象限8個線段來近似圓弧。端蓋樣式為cap_ROUND。

緩沖區(qū)操作總是返回多邊形結(jié)果。直線和點(diǎn)的負(fù)或零距離緩沖區(qū)始終為空多邊形。

這也是退化(零面積)多邊形緩沖區(qū)的結(jié)果。

Java中使用JTS實(shí)現(xiàn)WKT字符串讀取轉(zhuǎn)換線、查找LineString的list中距離最近的線、LineString做緩沖區(qū)擴(kuò)展并計(jì)算點(diǎn)在緩沖區(qū)內(nèi)的方位角,Java,java,list,python

然后獲取距離最近的線的名稱并輸出

??????? //獲取離目標(biāo)點(diǎn)位最近的線
??????? LineString lineString = findNearestLine(carPoint, 10D, regionList);
??????? String regionName = "區(qū)域位置為空";
??????? if (lineString != null) {
??????????? RegionDTO userData = (RegionDTO) lineString.getUserData();
??????????? regionName = userData.getRegionName();
??????? }

??????? System.out.println(regionName);

4、獲取坐標(biāo)點(diǎn)相對于該線的方位角

??????? String azimuth;

??????? if (!regionName.equals("區(qū)域位置為空")) {
??????????? List<LineString> lineStringList = regionMap.get(regionName);
??????????? LineString closeLine;
??????????? if (lineStringList.size() > 1) {
??????????????? closeLine = findNearestLine(carPoint, 10D, lineStringList);
??????????? } else {
??????????????? closeLine = lineStringList.get(0);
??????????? }
??????????? //獲取線的兩個端點(diǎn)
??????????? Point startPoint = closeLine.getStartPoint();
??????????? Point endPoint = closeLine.getEndPoint();
??????????? //獲取點(diǎn)位到兩個端點(diǎn)的距離
??????????? double startDistance = startPoint.distance(createPoint(carPoint.getX(), carPoint.getY()));
??????????? double endDistance = endPoint.distance(createPoint(carPoint.getX(), carPoint.getY()));
??????????? //獲取較近的點(diǎn)作為參考點(diǎn)判斷方位距離
??????????? if (startDistance <= endDistance) {
??????????????? //獲取方位角
??????????????? azimuth = regionName + DirectionUtil.getAzimuth(startPoint.getX(), startPoint.getY(), carPoint.getX(), carPoint.getY()) + "方向路口" + BigDecimal.valueOf(startDistance).intValue() + "米";
??????????? } else {
??????????????? azimuth = regionName + DirectionUtil.getAzimuth(endPoint.getX(), endPoint.getY(), carPoint.getX(), carPoint.getY()) + "方向路口" + BigDecimal.valueOf(endDistance).intValue() + "米";
??????????? }
??????? } else {
??????????? azimuth = "[" + carPoint.getX() + "," + carPoint.getY() + "]";
??????? }
??????? System.out.println(azimuth);

其中獲取方位角的工具類DirectionUtil.getAzimuth實(shí)現(xiàn)

import org.locationtech.jts.geom.LineSegment;

public class DirectionUtil {

??? /**
???? * 笛卡爾坐標(biāo)系
???? */
??? enum DirectionEnum {
??????? DUE_EAST("正東", "==0 || ==360"),
??????? DUE_NORTHEAST("東北", "==45"),
??????? DUE_NORTH("正北", "==90"),
??????? NORTH_NORTHWEST("西北", "90<theta<135"),
??????? DUE_WEST("正西", "==180"),
??????? WEST_SOUTHWEST("西南", "180<theta<225"),
??????? DUE_SOUTH("正南", "==270"),
??????? DUE_SOUTHEAST("東南", "==315");

??????? private String direction;
??????? private String describe;

??????? DirectionEnum(String direction, String describe) {
??????????? this.direction = direction;
??????????? this.describe = describe;
??????? }

??????? public String getDirection() {
??????????? return direction;
??????? }

??????? public void setDirection(String direction) {
??????????? this.direction = direction;
??????? }

??????? public String getDescribe() {
??????????? return describe;
??????? }

??????? public void setDescribe(String describe) {
??????????? this.describe = describe;
??????? }
??? }


??? /**
???? * 獲取方位角
???? *
???? * @param x1 觀測點(diǎn)x
???? * @param y1 觀測點(diǎn)y
???? * @param x2 目標(biāo)點(diǎn)x
???? * @param y2 目標(biāo)點(diǎn)y
???? * @return 返回距離觀測點(diǎn)的方位角
???? */
??? public static String getAzimuth(double x1, double y1, double x2, double y2) {
??????? LineSegment lineSegment = new LineSegment(x1, y1, x2, y2);
??????? double angle1 = lineSegment.angle();
??????? double angle = Math.toDegrees(lineSegment.angle());
??????? if (angle < 0) {
??????????? angle = angle + 360;
??????? }

??????? if ((0 < angle && angle < 12.5) || (347.5 < angle && angle < 360)) {
??????????? return DirectionEnum.DUE_EAST.getDirection();
??????? } else if (12.5 < angle && angle < 77.5) {
??????????? return DirectionEnum.DUE_NORTHEAST.getDirection();
??????? } else if (77.5 < angle && angle < 102.5) {
??????????? return DirectionEnum.DUE_NORTH.getDirection();
??????? } else if (102.5 < angle && angle < 167.5) {
??????????? return DirectionEnum.NORTH_NORTHWEST.getDirection();
??????? } else if (167.5 < angle && angle < 192.5) {
??????????? return DirectionEnum.DUE_WEST.getDirection();
??????? } else if (192.5 < angle && angle < 257.5) {
??????????? return DirectionEnum.WEST_SOUTHWEST.getDirection();
??????? } else if (257.5 < angle && angle < 282.5) {
??????????? return DirectionEnum.DUE_SOUTH.getDirection();
??????? } else if (282.5 < angle && angle < 347.5) {
??????????? return DirectionEnum.WEST_SOUTHWEST.getDirection();
??????? } else {
??????????? return "ERROR";
??????? }
??? }
}

邏輯就是對比目標(biāo)點(diǎn)到線的兩個端點(diǎn)的距離,取較近的進(jìn)行判斷,然后做方位角判斷。

運(yùn)行效果測試

Java中使用JTS實(shí)現(xiàn)WKT字符串讀取轉(zhuǎn)換線、查找LineString的list中距離最近的線、LineString做緩沖區(qū)擴(kuò)展并計(jì)算點(diǎn)在緩沖區(qū)內(nèi)的方位角,Java,java,list,python文章來源地址http://www.zghlxwxcb.cn/news/detail-707500.html

到了這里,關(guān)于Java中使用JTS實(shí)現(xiàn)WKT字符串讀取轉(zhuǎn)換線、查找LineString的list中距離最近的線、LineString做緩沖區(qū)擴(kuò)展并計(jì)算點(diǎn)在緩沖區(qū)內(nèi)的方位角的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 使用Java實(shí)現(xiàn)高效的字符串匹配算法

    摘要:字符串匹配是計(jì)算機(jī)領(lǐng)域中的一個重要問題,有著廣泛的應(yīng)用場景。在本篇博客文章中,我們將介紹幾種高效的字符串匹配算法,并給出使用Java語言實(shí)現(xiàn)的代碼示例,希望能對讀者理解和應(yīng)用這些算法有所幫助。 一、KMP算法 KMP算法(Knuth-Morris-Pratt算法)是一種經(jīng)典的

    2024年02月16日
    瀏覽(30)
  • java 處理常量字符串過長 & springboot 項(xiàng)目讀取 resouces 文件夾下的文件內(nèi)容

    java 處理常量字符串過長 & springboot 項(xiàng)目讀取 resouces 文件夾下的文件內(nèi)容

    項(xiàng)目里面有一長串的加密字符串(最長的萬多個字符),需要拼接作為參數(shù)發(fā)送給第三方。 如果我們使用 枚舉 定義的話,idea 編譯的時候就會出現(xiàn)編譯報(bào)錯 網(wǎng)上還有一個說法,說是編譯器問題,修改 idea 工具的編譯為 eclipse 即可。 但是結(jié)果我仍然不滿意,所以我決定把他放在

    2023年04月13日
    瀏覽(92)
  • springboot yml文件自定義配置的讀取、使用 字符串 數(shù)組 對象 集合

    springboot yml文件自定義配置的讀取、使用 字符串 數(shù)組 對象 集合

    .yml 配置 controller代碼 實(shí)體類 Student.java Users.java User.java 方式一、 http://localhost:9801/test/test1 方式二、 http://localhost:9801/test/test2 方式三、 http://localhost:9801/test/test3 參考: SpringBoot:yml文件詳解-CSDN博客 https://www.jb51.net/article/216769.htm

    2024年02月05日
    瀏覽(25)
  • c++讀取字符串字符時出錯

    c++讀取字符串字符時出錯

    這是我做的一個c++爬蟲程序但是在抓取網(wǎng)頁的時候string類型傳遞出現(xiàn)了問題 以下是圖片代碼 ?url的值是 \\\"http://desk.zol.com.cn/\\\" 我不知道為什么數(shù)據(jù)傳遞會出問題 請大佬指教 后面重新啟動一遍編譯器查一查斷點(diǎn)有突然沒問題了 ,真是個玄學(xué)的問題。我還以為是mallco出問題了

    2024年02月12日
    瀏覽(25)
  • Java如何實(shí)現(xiàn)截取字符串

    Java如何實(shí)現(xiàn)截取字符串

    在實(shí)際工作中有一些地方需要用到截取字符串的方法,所以在此記錄下截取字符串的幾種方法。 .substring() StringUtils.substring() split()+正則表達(dá)式 這個是比較常用的一個方法。 此方法有兩種形式: 實(shí)例代碼: 需要注意的是: 計(jì)數(shù)從0開始 ,如果超過了字符串長度則會報(bào)錯: 計(jì)

    2023年04月18日
    瀏覽(23)
  • 字符串去重(Java實(shí)現(xiàn))

    步驟 輸入字符串 字符串轉(zhuǎn)換成字符串?dāng)?shù)組 數(shù)組轉(zhuǎn)換為List集合 將List集合轉(zhuǎn)化為Set集合(Set集合不允許重復(fù)值) Set集合轉(zhuǎn)換為數(shù)組 數(shù)組拼接成字符串 具體代碼實(shí)現(xiàn)如下: 其實(shí)原理很簡單,就是利用Set集合的特性來消除重復(fù)元素。

    2024年02月13日
    瀏覽(24)
  • Java實(shí)現(xiàn)字符串加密與解密

    我們在設(shè)計(jì)登錄程序時需要用到保存用戶名和密碼的功能,如果是直接寫入到txt文件中保存很容易被木馬程序識破,所以就必須先對密碼加密,只留存密文。 今天介紹的是使用 十六進(jìn) 制轉(zhuǎn)換的方式加密數(shù)據(jù)。 得到結(jié)果:?757376662d312d6d7064626d697074752d323534342d717974646b 現(xiàn)在我們將

    2024年02月11日
    瀏覽(25)
  • 如何讀取帶空格的字符串?

    如何讀取帶空格的字符串?

    scanf()函數(shù)在讀取字符時,識別到空格就會終止讀取,那么如何讀取帶空格的字符串呢? 從標(biāo)準(zhǔn)輸入(stdin)(指的是鍵盤輸入)讀取字符,并將它們作為 C 字符串存儲到 str 中,直到達(dá)到換行字符或文件末尾。 即gets()函數(shù)會一直讀取字符直到遇到換行符n(回車)或文件末尾截

    2024年02月07日
    瀏覽(20)
  • Java實(shí)現(xiàn)兩字符串相似度算法

    Java實(shí)現(xiàn)兩字符串相似度算法

    編輯距離:是衡量兩個字符串之間差異的度量,它表示 將一個字符串轉(zhuǎn)換為另一個字符串所需的最少編輯操作次數(shù) (插入、刪除、替換)。 計(jì)算方法可以有多種,其中一種 常見 的方法是 將編輯距離歸一化為0到1之間的范圍 (歸一化編輯距離(Normalized Edit Distance)), 將編

    2024年02月05日
    瀏覽(26)
  • Java使用substring()方法截取字符串

    substring()方法是java String類的常用方法,作用是返回字符串的子字符串。 beginIndex是起始索引值(包括),從0開始。該方法將字符串從beginIndex位置開始截取,一直到字符串末尾。 示例: 輸出: beginIndex是起始索引值(包括),從0開始,endIndex是結(jié)束索引值(不包括)。該方法

    2024年02月13日
    瀏覽(29)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包