ArcGIS for Desktop'ta satır belirtilen mesafeye göre genişletiliyor mu?


11

Ok sembolleri olan tamamen estetik bir katmanım var. Bazıları doğru görünmüyor çünkü çizgi çok küçük. Bu satırı belirli bir sayıya (örn. 2 metre) genişletmem gereken 50 kayıt seçtim. Çizgi genişletme aracı, çizgileri yalnızca belirtilen bir kavşağa genişletir, bu nedenle bu araç aradığım şey değildir.

Şekil uzunluğu alanını düzenlemeyi denedim ama izin vermiyor. Bunu alan hesaplayıcısıyla veya editör araç çubuğunda yapmanın basit bir yolu var mı?


1
, gdb, fgdb biçimindeki veriler nedir? temel, standart, gelişmiş var mı?
Brad Nesom

Şekil ve gelişmiş.
GISKid

Açıklığa kavuşturabilir miyim, çok satırlı bir şekil dosyasındaki her özelliği mi yoksa yalnızca seçilen özellikleri mi genişletmek istediniz?

Uzantınızı bitiş noktasına dayandırmak istiyorsanız, önceki köşeye gidebilir ve bu iki nokta arasındaki eğimi belirleyebilirsiniz. Ardından, uç nokta tepe noktasını , söz konusu eğime göre x mesafenizi hareket ettirebilirsiniz .
Paul

@Paul, bunu yapmak için bir senaryo yazıyorum, ancak biraz daha karmaşık çünkü çok parçalı polietilenleri hesaba katmanız gerekiyor. Yani, her bölüm için başlangıç ​​ve bitiş noktalarına ve komşu noktalarına bakmanız gerekir. GISKid'in tüm özellikleri ilk önce genişletmekle ilgilendiğini bilmeliyim.

Yanıtlar:


12

Bence herhangi bir köşe sayısının satırları için aşağı aldım. Arcpy ile hiç uğraşmadığım için çok bölümlü çizgiler denemedim. Geometri nesneleri için lastPoint özelliğine yazma erişimi olmadığından kodlama biraz zorlaştı. (Bu benim ilk düşüncem olan) eğimi kullanmak yerine, bu SO sorunun kodunu kullandım . Trigonometriye dayanmaz, bu yüzden biraz daha verimli olmalıdır. Aşağıdaki kod, bir çizginin uç noktasını, bir çizginin son iki köşeden uzaması boyunca uzanan yeni bir koordinata taşıyarak çalışır. Bir şekil dosyasında test ettim.

from math import hypot
import collections
from operator import add
import arcpy

layer = arcpy.GetParameterAsText(0)
distance = float(arcpy.GetParameterAsText(1))

#Computes new coordinates x3,y3 at a specified distance
#along the prolongation of the line from x1,y1 to x2,y2
def newcoord(coords, dist):
    (x1,y1),(x2,y2) = coords
    dx = x2 - x1
    dy = y2 - y1
    linelen = hypot(dx, dy)

    x3 = x2 + dx/linelen * dist
    y3 = y2 + dy/linelen * dist    
    return x3, y3

#accumulate([1,2,3,4,5]) --> 1 3 6 10 15
#Equivalent to itertools.accumulate() which isn't present in Python 2.7
def accumulate(iterable):    
    it = iter(iterable)
    total = next(it)
    yield total
    for element in it:
        total = add(total, element)
        yield total

#OID is needed to determine how to break up flat list of data by feature.
coordinates = [[row[0], row[1]] for row in
               arcpy.da.SearchCursor(layer, ["OID@", "SHAPE@XY"], explode_to_points=True)]

oid,vert = zip(*coordinates)

#Construct list of numbers that mark the start of a new feature class.
#This is created by counting OIDS and then accumulating the values.
vertcounts = list(accumulate(collections.Counter(oid).values()))

#Grab the last two vertices of each feature
lastpoint = [point for x,point in enumerate(vert) if x+1 in vertcounts or x+2 in vertcounts]

#Convert flat list of tuples to list of lists of tuples.
#Obtain list of tuples of new end coordinates.
newvert = [newcoord(y, distance) for y in zip(*[iter(lastpoint)]*2)]    

j = 0
with arcpy.da.UpdateCursor(layer, "SHAPE@XY", explode_to_points=True) as rows:
    for i,row in enumerate(rows):
        if i+1 in vertcounts:            
            row[0] = newvert[j]
            j+=1
            rows.updateRow(row)

OID'ye dayalı kategoriler için sembolojiyi sonunda ok olarak ayarladım, böylece özellikler arasındaki ayrımı görmek daha kolay olacak. Etiketleme köşeleri sayacak şekilde ayarlanmıştır.resim açıklamasını buraya girin


Bu bana çok yardımcı oldu! Ancak, distance parametresi orijinal çizgi özelliklerindeki bir alana dayanabiliyorsa, bu benim özel durumumda daha da yardımcı olacaktır. Bu kendim uygulamayı denedim ve bir şekilde "newvert =" satırındaki mesafeleri yinelemek zorunda olacağını biliyorum ama bunu uygulamakta zorlanıyorum. Bunu yapmak için kodunuzu genişletmek mümkün olsaydı çok minnettar olurum!
GeoJohn

Komut dosyasını Python konsolundan çalıştırıyorsanız, görünümünüzü güncellemeyi unutmayın. Çizgilerim birkaç "başarısız" denemeden sonra gerçekten uzun sürdü.
EikeMike

2

Genişletmek istediğiniz satırları seçerseniz ne olur?
Bu satırları istenen uzatma miktarına göre tamponlayın.
Bunu bir fc satırına dönüştürün.
Sonra kavşağa kadar uzatın.
Ortadaki çizginin üst üste binmesini önlemek için arabelleğin diğer ucunu kırmanız ve silmeniz gerekebilir. (Yaptığınız veya yapmak istediğiniz şeyin bir ekran görüntüsünü görmedim)
Ya da ettools'ta bir araç olduğunu düşünüyorum (işlevselliği görmek için kontrol ediyorum ve ücretsiz
mi ) Et araçlarında yararlı bir şey bulamadım bazı (eski) vb kodları için bu konuyu bulun . ve bazı pitonlar için bir istek. takip edebilir ve ideas.arcgis.com web sitesine bakabilirsiniz .


2

Burada, herhangi bir sayıda düğüm noktasından oluşan çok parçalı polininler ile çalışan bir yöntem var. Açık kaynak kodlu GIS Whitebox GAT ( http://www.uoguelph.ca/~hydrogeo/Whitebox/ ) kullanır. Sadece Whitebox'ı indirin, Scripter'ı açın (araç çubuğundaki kod simgesi), kodlama dilini Groovy olarak değiştirin, aşağıdaki kodu yapıştırın ve 'ExtendVectorLines.groovy' olarak kaydedin. Scripter'dan veya Whitebox'ı bir sonraki başlatışınızda, Vektör Araçları araç kutusunda bir eklenti aracı olarak görünecektir. Girdi olarak bir şekil dosyası ve bir uzatma mesafesi alır. Aracı, Whitebox GAT'ın bir sonraki genel sürümüne ekleyeceğim.

/*
 * Copyright (C) 2013 Dr. John Lindsay <jlindsay@uoguelph.ca>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

import java.awt.event.ActionListener
import java.awt.event.ActionEvent
import java.io.File
import java.util.concurrent.Future
import java.util.concurrent.*
import java.util.Date
import java.util.ArrayList
import whitebox.interfaces.WhiteboxPluginHost
import whitebox.geospatialfiles.ShapeFile
import whitebox.geospatialfiles.shapefile.*
import whitebox.ui.plugin_dialog.ScriptDialog
import whitebox.utilities.FileUtilities;
import groovy.transform.CompileStatic

// The following four variables are required for this 
// script to be integrated into the tool tree panel. 
// Comment them out if you want to remove the script.
def name = "ExtendVectorLines"
def descriptiveName = "Extend Vector Lines"
def description = "Extends vector polylines by a specified distance"
def toolboxes = ["VectorTools"]

public class ExtendVectorLines implements ActionListener {
private WhiteboxPluginHost pluginHost
private ScriptDialog sd;
private String descriptiveName

public ExtendVectorLines(WhiteboxPluginHost pluginHost, 
    String[] args, def descriptiveName) {
    this.pluginHost = pluginHost
    this.descriptiveName = descriptiveName

    if (args.length > 0) {
        final Runnable r = new Runnable() {
            @Override
            public void run() {
                execute(args)
            }
        }
        final Thread t = new Thread(r)
        t.start()
    } else {
        // Create a dialog for this tool to collect user-specified
        // tool parameters.
        sd = new ScriptDialog(pluginHost, descriptiveName, this)    

        // Specifying the help file will display the html help
        // file in the help pane. This file should be be located 
        // in the help directory and have the same name as the 
        // class, with an html extension.
        def helpFile = "ExtendVectorLines"
        sd.setHelpFile(helpFile)

        // Specifying the source file allows the 'view code' 
        // button on the tool dialog to be displayed.
        def pathSep = File.separator
        def scriptFile = pluginHost.getResourcesDirectory() + "plugins" + pathSep + "Scripts" + pathSep + "ExtendVectorLines.groovy"
        sd.setSourceFile(scriptFile)

        // add some components to the dialog
        sd.addDialogFile("Input file", "Input Vector Polyline File:", "open", "Vector Files (*.shp), SHP", true, false)
        sd.addDialogFile("Output file", "Output Vector File:", "close", "Vector Files (*.shp), SHP", true, false)
        sd.addDialogDataInput("Distance:", "Enter a distance", "", true, false)

        // resize the dialog to the standard size and display it
        sd.setSize(800, 400)
        sd.visible = true
    }
}

// The CompileStatic annotation can be used to significantly
// improve the performance of a Groovy script to nearly 
// that of native Java code.
@CompileStatic
private void execute(String[] args) {
    try {
        int i, f, progress, oldProgress, numPoints, numParts
        int part, startingPointInPart, endingPointInPart
        double x, y, x1, y1, x2, y2, xSt, ySt, xEnd, yEnd, slope;
        ShapefileRecordData recordData;
        double[][] geometry
        int[] partData
        if (args.length != 3) {
            pluginHost.showFeedback("Incorrect number of arguments given to tool.")
            return
        }
        // read the input parameters
        String inputFile = args[0]
        String outputFile = args[1]
        double d = Double.parseDouble(args[2]) // extended distance

        def input = new ShapeFile(inputFile)

        // make sure that input is of a POLYLINE base shapetype
        ShapeType shapeType = input.getShapeType()
        if (shapeType.getBaseType() != ShapeType.POLYLINE) {
            pluginHost.showFeedback("Input shapefile must be of a POLYLINE base shapetype.")
            return
        }

        int numFeatures = input.getNumberOfRecords()

        // set up the output files of the shapefile and the dbf
        ShapeFile output = new ShapeFile(outputFile, shapeType);
        FileUtilities.copyFile(new File(input.getDatabaseFile()), new File(output.getDatabaseFile()));

        int featureNum = 0;
        for (ShapeFileRecord record : input.records) {
            featureNum++;
            PointsList points = new PointsList();
            recordData = getXYFromShapefileRecord(record);
            geometry = recordData.getPoints();
            numPoints = geometry.length;
            partData = recordData.getParts();
            numParts = partData.length;

            for (part = 0; part < numParts; part++) {
                startingPointInPart = partData[part];
                if (part < numParts - 1) {
                    endingPointInPart = partData[part + 1] - 1;
                } else {
                    endingPointInPart = numPoints - 1;
                }

                // new starting poing
                x1 = geometry[startingPointInPart][0]
                y1 = geometry[startingPointInPart][1]

                x2 = geometry[startingPointInPart + 1][0]
                y2 = geometry[startingPointInPart + 1][2]

                if (x1 - x2 != 0) {
                    slope = Math.atan2((y1 - y2) , (x1 - x2))
                    xSt = x1 + d * Math.cos(slope)
                    ySt = y1 + d * Math.sin(slope)
                } else {
                    xSt = x1
                    if (y2 > y1) {
                        ySt = y1 - d
                    } else {
                        ySt = y1 + d
                    }
                }

                // new ending point
                x1 = geometry[endingPointInPart][0]
                y1 = geometry[endingPointInPart][3]

                x2 = geometry[endingPointInPart - 1][0]
                y2 = geometry[endingPointInPart - 1][4]

                if (x1 - x2 != 0) {
                    slope = Math.atan2((y1 - y2) , (x1 - x2))
                    xEnd = x1 + d * Math.cos(slope)
                    yEnd = y1 + d * Math.sin(slope)
                } else {
                    xEnd = x1
                    if (y2 < y1) {
                        yEnd = y1 - d
                    } else {
                        yEnd = y1 + d
                    }
                }

                points.addPoint(xSt, ySt)
                for (i = startingPointInPart; i <= endingPointInPart; i++) {
                    x = geometry[i][0]
                    y = geometry[i][5]
                    points.addPoint(x, y)
                }
                points.addPoint(xEnd, yEnd)

            }

            for (part = 0; part < numParts; part++) {
                partData[part] += part * 2
            }

            switch (shapeType) {
                case ShapeType.POLYLINE:
                    PolyLine line = new PolyLine(partData, points.getPointsArray());
                    output.addRecord(line);
                    break;
                case ShapeType.POLYLINEZ:
                    PolyLineZ polyLineZ = (PolyLineZ)(record.getGeometry());
                    PolyLineZ linez = new PolyLineZ(partData, points.getPointsArray(), polyLineZ.getzArray(), polyLineZ.getmArray());
                    output.addRecord(linez);
                    break;
                case ShapeType.POLYLINEM:
                    PolyLineM polyLineM = (PolyLineM)(record.getGeometry());
                    PolyLineM linem = new PolyLineM(partData, points.getPointsArray(), polyLineM.getmArray());
                    output.addRecord(linem);
                    break;
            }
        }

        output.write();

        // display the output image
        pluginHost.returnData(outputFile)

        // reset the progress bar
        pluginHost.updateProgress(0)
    } catch (Exception e) {
        pluginHost.showFeedback(e.getMessage())
    }
}


@CompileStatic
private ShapefileRecordData getXYFromShapefileRecord(ShapeFileRecord record) {
    int[] partData;
    double[][] points;
    ShapeType shapeType = record.getShapeType();
    switch (shapeType) {
        case ShapeType.POLYLINE:
            whitebox.geospatialfiles.shapefile.PolyLine recPolyLine =
                    (whitebox.geospatialfiles.shapefile.PolyLine) (record.getGeometry());
            points = recPolyLine.getPoints();
            partData = recPolyLine.getParts();
            break;
        case ShapeType.POLYLINEZ:
            PolyLineZ recPolyLineZ = (PolyLineZ) (record.getGeometry());
            points = recPolyLineZ.getPoints();
            partData = recPolyLineZ.getParts();
            break;
        case ShapeType.POLYLINEM:
            PolyLineM recPolyLineM = (PolyLineM) (record.getGeometry());
            points = recPolyLineM.getPoints();
            partData = recPolyLineM.getParts();
            break;
        default: // should never hit this.
            points = new double[1][2];
            points[1][0] = -1;
            points[1][6] = -1;
            break;
    }
    ShapefileRecordData ret = new ShapefileRecordData(points, partData)
    return ret;
}

@CompileStatic
class ShapefileRecordData {
    private final double[][] points
    private final int[] parts
    ShapefileRecordData(double[][] points, int[] parts) {
        this.points = points
        this.parts = parts
    }

    double[][] getPoints() {
        return points
    }

    int[] getParts() {
        return parts
    }

}

@Override
public void actionPerformed(ActionEvent event) {
    if (event.getActionCommand().equals("ok")) {
        final def args = sd.collectParameters()
        sd.dispose()
        final Runnable r = new Runnable() {
            @Override
            public void run() {
                execute(args)
            }
        }
        final Thread t = new Thread(r)
        t.start()
    }
}
}

if (args == null) {
pluginHost.showFeedback("Plugin arguments not set.")
} else {
def f = new ExtendVectorLines(pluginHost, args, descriptiveName)
}

resim açıklamasını buraya girin

resim açıklamasını buraya girin


Kodu isteğe bağlı olarak değiştirdim, böylece isteğe bağlı olarak satır başlangıcını, satır sonlarını veya her iki ucu da genişletebilirsiniz. Değiştirilmiş araçla ilgileniyorsanız bana bildirin.

Yardımın için teşekkürler! WhiteBox'a bakacağım, daha önce hiç duymadım. Guelph'in böyle projeleri olduğunu görmek çok güzel! Ben bir UWindsor öğrencisiyim.
GISKid

Windsor çok mükemmel bir yerdir! En son sürümü (3.0.5) yayınladım ve satırları genişletmek için güncellenmiş aracı içeriyor. Benim için herhangi bir sorun veya geri bildiriminiz varsa bana bildirin.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.