簡體   English   中英

如何使用Java JTS將線串每x米分成幾部分

[英]How to split linestring into parts every x meters with java JTS

我正在嘗試將JTS和postgis用於基於spring的后端。 雖然我了解JTS的基礎知識,但我不知道如何實現

只需使用Java實現geographiclib -我相信你想GeodesicLine ; 然后使用JTS和postgis將以這種方式生成的線串坐標獲取到postgresql中。 這個JavaScript中的測地線示例應該可以幫助您入門。

我編寫了下面的方法,該方法可以滿足您的要求,並使用JTS LineSegment對象計算拆分點:

public ArrayList<LineString> splitLineStringIntoParts(LineString ls, double length){
    // result list for linestrings
    ArrayList<LineString> resultList = new ArrayList();
    // list for linesegments from input linestring
    ArrayList<LineSegment> lineSegmentList = new ArrayList();
    // create LineSegment objects from input linestring and add them to list
    for(int i = 1; i < ls.getCoordinates().length; i++){
        lineSegmentList.add(new LineSegment(ls.getCoordinates()[i-1], ls.getCoordinates()[i]));
    }
    LineString currentLineString = null;
    double neededLength = length;
    for(LineSegment s : lineSegmentList){
        while(s.getLength() > 0){
            // case: current segment is small enough to be added to the linestring
            if(s.getLength() <= neededLength){
                // create linestring if it does not exist 
                if(currentLineString == null){
                    currentLineString = new GeometryFactory().createLineString(new Coordinate[]{new Coordinate(s.p0), new Coordinate(s.p1)});
                // just add the new endpoint otherwise
                } else {
                    Coordinate[] coords = new Coordinate[currentLineString.getCoordinates().length + 1];
                    // copy old coordinates
                    System.arraycopy(currentLineString.getCoordinates(), 0, coords, 0, currentLineString.getCoordinates().length);
                    // add new coordinate at the end
                    coords[coords.length-1] = new Coordinate(s.p1);
                    // create new linestring
                    currentLineString = new GeometryFactory().createLineString(coords);
                }
                neededLength -= s.getLength();
                s.setCoordinates(s.p1, s.p1);
                // add linestring to result list if needed length is 0
                if(neededLength == 0){
                    resultList.add(currentLineString);
                    currentLineString = null;
                    neededLength = length;
                }
            // current segment needs to be cut and added to the linestring
            } else {
                // get coordinate at desired distance (endpoint of linestring)
                Coordinate endPoint = s.pointAlong(neededLength/s.getLength());
                // create linestring if it does not exist 
                if(currentLineString == null){
                    currentLineString = new GeometryFactory().createLineString(new Coordinate[]{new Coordinate(s.p0), endPoint});
                // just add the new endpoint otherwise
                } else {
                    // add new coordinate to linestring
                    Coordinate[] coords = new Coordinate[currentLineString.getCoordinates().length + 1];
                    // copy old coordinates
                    System.arraycopy(currentLineString.getCoordinates(), 0, coords, 0, currentLineString.getCoordinates().length);
                    // add new coordinate at the end
                    coords[coords.length-1] = endPoint;
                    currentLineString = new GeometryFactory().createLineString(coords);
                }
                // add linestring to result list
                resultList.add(currentLineString);
                // reset needed length
                neededLength = length;
                // reset current linestring
                currentLineString = null;
                // adjust segment (calculated endpoint is the new startpoint)
                s.setCoordinates(endPoint, s.p1);
            }
        }
    }
    // add last linestring if there is a rest
    if(neededLength < length){
        resultList.add(currentLineString);
    }
    return resultList;
}

我還需要編寫split函數,所以我找到了關於stackoverflow的解決方案,但是找不到一些有用的信息。所以我編寫了follow方法並回答了您的問題;

public List<LineString> lineSplit(LineString lineString,double meters) {
    List<LineString> results = new ArrayList<>();
    List<LineSegment> segments = new ArrayList<>();
    // first split linestring to segements[]
    for(int i = 1; i < lineString.getCoordinates().length; i++){
        segments.add(new LineSegment(lineString.getCoordinates()[i-1], lineString.getCoordinates()[i]));
    }
    // remainLegnth means that last segment's length dont enough to split to one segement which length is meters
    // neededLength means that current segment need how many meters to create a new segment
    double remainLength = 0D;
    double neededLength = 0D;
    // remainCoors means that if the last iteartor dont create a new segment,also mean  last segment
    // is too short ,even add remains length can't create a new segment;so, we should add this segment's start
    // point and end point to remainCoors
    List<Coordinate> remainCoors = new ArrayList<>();
    // netxStartPoint to store the next segment's start point 
    Coordinate netxStartPoint = null;
    for(int i=0;i<segments.size();i++) {
        LineSegment seg = segments.get(i);
        neededLength = meters-remainLength;
        remainLength += seg.getLength();
        netxStartPoint = seg.p0;
        while(remainLength>=meters) {
            remainCoors.add(netxStartPoint);
            Coordinate endPoint = seg.pointAlong(neededLength/seg.getLength());
            // to remove the adjacent and same vertx
            for(int j=0;j<remainCoors.size()-1;j++) {
                if(remainCoors.get(j).equals(remainCoors.get(j+1))) {
                    remainCoors.remove(j);
                }
            }
            remainCoors.add(endPoint);
            results.add(lineString.getFactory().createLineString(remainCoors.toArray(new Coordinate[remainCoors.size()])));
            remainCoors = new ArrayList<>();
            netxStartPoint = endPoint;
            remainLength -= meters;
            neededLength += meters;
        }
        remainCoors.add(netxStartPoint);
        remainCoors.add(seg.p1);
    }
    for(int j=0;j<remainCoors.size()-1;j++) {
        if(remainCoors.get(j).equals(remainCoors.get(j+1))) {
            remainCoors.remove(j);
        }
    }
    if(remainCoors.size()>=2) {
        results.add(lineString.getFactory().createLineString(remainCoors.toArray(new Coordinate[remainCoors.size()])));
    }
    return results;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM