0

I am a complete newbie to ArcGIS/ArcPy. I am creating a new Python Toolbox, that reads in a GPFeatureLayer, and also should return one. I read in the values of a GPFeatureLayer row by row. Then I perform some calculations on them, to obtain indices of rows that are important for me. This results in a data frame.

Now I want to create a new GPFeatureLayer that only contains the rows that are specified by my indices. I thought that there may be a function to create a new GPFeatureLayer from a df, but is there any other way how to get to the goal?

This is my code:

import arcpy
from arcgis.gis import GIS
from arcgis import features
from arcgis.features import FeatureLayerCollection
import arcgis
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import r2_score


class Toolbox(object):
    def __init__(self):
        """Define the toolbox (the name of the toolbox is the name of the
        .pyt file)."""
        self.label = "Toolbox"
        self.alias = "toolbox"

        # List of tool classes associated with this toolbox
        self.tools = [Tool]


class Tool(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "ComparingSegments"
        self.description = ""
        self.canRunInBackground = False

    def getParameterInfo(self):
        """Define parameter definitions"""
        p0 = arcpy.Parameter(displayName="Input Feature Layer",
                             name="input_feature_layer",
                             datatype="GPFeatureLayer",
                             parameterType="Required",
                             direction="Input")

        p1 = arcpy.Parameter(displayName="Output Feature Layer",
                             name="output_feature_layer",
                             datatype="DEFeatureClass",
                             parameterType="Required",
                             direction="Output")

        params = [p0, p1]

        return params

    def isLicensed(self):
        """Set whether tool is licensed to execute."""
        return True

    def updateParameters(self, parameters):
        """Modify the values and properties of parameters before internal
        validation is performed.  This method is called whenever a parameter
        has been changed."""

        return

    def updateMessages(self, parameters):
        """Modify the messages created by internal validation for each tool
        parameter.  This method is called after internal validation."""
        return


    def execute(self, parameters, messages):
        """The source code of the tool."""

        input_feature_layer = parameters[0].valueAsText

        fields = ["OBJECTID", "Shape", "ORIG_FID", "ORIG_SEQ", "Shape_Length", "Z_Mean"]
        z_means = []
        shape = []
        orig_fid = []
        orig_seq = []
        shape_length = []
        object_id = []

        with arcpy.da.SearchCursor(input_feature_layer, fields) as cursor:
            for row in cursor:
                z_means.append(float(row[5]))
                shape.append(int(row[4]))
                orig_fid.append(int(row[3]))
                orig_seq.append(int(row[2]))
                shape_length.append(int(row[1]))
                object_id.append(int(row[0]))

        startIndex, endIndex = someFunction(z_means, object_id)

        data = {"OBJECTID": object_id[startIndex:endIndex],
                "Shape": shape[startIndex:endIndex],
                "ORIG_FID": orig_fid[startIndex:endIndex],
                "ORIG_SEQ": orig_seq[startIndex:endIndex],
                "Shape_Length": shape_length[startIndex:endIndex],
                "Z_Mean": z_means[startIndex:endIndex]}

        df = pd.DataFrame(data)

        # HOW TO CREATE AND RETURN NEW GPFeatureLayer FROM DF???

        return

    def postExecute(self, parameters):
        """This method takes place after outputs are processed and
        added to the display."""
        return result
3
  • You dont have to create a new feature layer from your dataframe, you can simply select the rows from the original feature layer and export. The Export Features tool would handle the creation and also the selection. If you can maintain the OID or another unique value in the data frame and then base the selection from the original feature layer based on on these values. Commented Nov 25, 2023 at 13:25
  • 1
    Thanks, I dont know what you mean by "export" and "Export Tool", but as you suggested, I just select the rows that I need from the original layer, and return the subset. (See answer) Commented Nov 27, 2023 at 13:11
  • Basically the Export Features is one tool that will perform what you have done in three with MakeFeatureLayer, SelectLayerByAttribute, and Copy. pro.arcgis.com/en/pro-app/latest/tool-reference/conversion/…, just use the where clause for your selection. Commented Nov 27, 2023 at 15:04

1 Answer 1

0

I found this answer. It may not be the right way to do it, but it works for me.

import arcpy
from arcgis.gis import GIS
from arcgis import features
from arcgis.features import FeatureLayerCollection
import arcgis
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import r2_score


class Toolbox(object):
    def __init__(self):
        """Define the toolbox (the name of the toolbox is the name of the
        .pyt file)."""
        self.label = "Toolbox"
        self.alias = "toolbox"

        # List of tool classes associated with this toolbox
        self.tools = [Tool]


class Tool(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "ComparingSegments"
        self.description = ""
        self.canRunInBackground = False

    def getParameterInfo(self):
        """Define parameter definitions"""
        p0 = arcpy.Parameter(displayName="Input Feature Layer",
                             name="input_feature_layer",
                             datatype="GPFeatureLayer",
                             parameterType="Required",
                             direction="Input")

        p1 = arcpy.Parameter(displayName="Output Feature Layer",
                             name="output_feature_layer",
                             datatype="DEFeatureClass",
                             parameterType="Derived",
                             direction="Output")

        params = [p0, p1]

        return params

    def isLicensed(self):
        """Set whether tool is licensed to execute."""
        return True

    def updateParameters(self, parameters):
        """Modify the values and properties of parameters before internal
        validation is performed.  This method is called whenever a         
        parameter has been changed."""

        return

    def updateMessages(self, parameters):
        """Modify the messages created by internal validation for each 
        tool parameter.  This method is called after internal 
        validation."""
        return


    def execute(self, parameters, messages):
        """The source code of the tool."""

        input_feature_layer = parameters[0].valueAsText

        fields = ["OBJECTID", "Z_Mean"]
        z_means = []
        object_id = []

        with arcpy.da.SearchCursor(input_feature_layer, fields) as cursor:
            for row in cursor:
            z_means.append(float(row[5]))
            object_id.append(int(row[0]))

        startIndex, endIndex = someFunction(z_means, object_id)

        arcpy.MakeFeatureLayer_management(input_feature_layer, "tmp_lyr")
        arcpy.SelectLayerByAttribute_management("tmp_lyr", 
        "SUBSET_SELECTION", "OBJECTID >= "+str(startIndex)+" AND 
        OBJECTID <="+str(endIndex))

        fnl_lyr = arcpy.CopyFeatures_management("tmp_lyr",             
                  "C:/data/project.gdb/newLayer")
        aprx = arcpy.mp.ArcGISProject("CURRENT")
        aprxMap = aprx.listMaps("Map")[0] 
        aprxMap.addDataFromPath(fnl_lyr)

        arcpy.SetParameterAsText(1, fnl_lyr)

        return parameters

    def postExecute(self, parameters):
        """This method takes place after outputs are processed and
        added to the display."""
        return parameters

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.