<jupyter_start><jupyter_text>Working with ArcPy Geometries   Overview- Geometry Objects- Geometry Objects in Geoprocessing Tools- Workspaces- Listing Functions- Creating Data    + Creating Unique Names    + Spatial Reference Object- Cursor Objects    + da module      Workspaces- `management` allows for the creation of workspaces- What can you create?    + Enterprise Geodatabases    + File Geodatabases    + Folders    + Sqlite Databases<jupyter_code>import arcpy
fgdb = arcpy.management.CreateFileGDB(out_folder_path=r"c:\temp",
                                      out_name="amazing.gdb")[0]
print(fgdb)<jupyter_output>c:\temp\amazing.gdb<jupyter_text>Listing Information- ArcPy provides methods to list informations    + workspaces    + fields    + feature classes    + much more... - Full list of methods can be found [here](http://pro.arcgis.com/en/pro-app/arcpy/functions/alphabetical-list-of-arcpy-functions.htm)```pythonimport arcpyfrom arcpy import envenv.workspace = r"c:\temp"for fc in arcpy.ListFeatureClasses():    print(fc)```  Geometry Objects- Geometry objects define a spatial location and an associated geometric shape- ArcPy Supports:    + Point, Polyline, Polygon, Multipoints- The class has a set of `properties` and `methods`  Point Geometry- Simplest Geometry (x,y {z}) - Construction requires two steps:    + 1. Create a arcpy.Point object    + 2. Pass the arcpy.Point object to a PointGeometry class<jupyter_code>import arcpy
point = arcpy.Point(25282, 43770)
ptGeometry = arcpy.PointGeometry(point)
ptGeometry.JSON<jupyter_output><empty_output><jupyter_text>Array Object- Contain points and arrays- Used to construct geometries higher than point geometries     + Polylines    + MultiPoints    + Polygons- Arrays can be reused to save object creation time.- Arrays support the follow methods:    + add    + append    + removeAll    + remove```python>>> import arcpy>>> coords = [[0,0], [1,1], [2,2],[2,0],[0,0]]>>> array = arcpy.Array([arcpy.Point(*xy) for xy in coords])>>> print(arcpy.Polygon(array).JSON)'{"rings":[[[0,0],[1.0001220703125,1.0001220703125],[2.0001220703125,2.0001220703125],[2.0001220703125,0],[0,0]]],"spatialReference":{"wkid":null}}'```  Array Object Creating Multipart Geometries - To create Multipart Geometries pass multiple `Array` objects into a geometry object```pythonimport arcpyfirst_part = arcpy.Array([arcpy.Point(-77.4349451, 37.5408265),                          arcpy.Point(-78.6384349, 35.7780943)])second_part = arcpy.Array([arcpy.Point(-79.7910143, 36.0786785),                           arcpy.Point(-80.8546435, 35.2315402)])array = arcpy.Array([first_part, second_part])multipart_feature = arcpy.Polyline(array)```  Polyline Geometry- Consists of at least 2 points- Unlike OGC Geometries a Poyline can be single or multipart segments    + This means there are less geometry objects to worry about (simple geometry API)```pythonimport arcpyfeature_info = [[[1, 2], [2, 4], [3, 7]],                [[6, 8], [5, 7], [7, 2], [9, 5]]] A list that will hold each of the Polyline objectsfeatures = []for feature in feature_info:     Create a Polyline object based on the array of points     Append to the list of Polyline objects    features.append(        arcpy.Polyline(            arcpy.Array([arcpy.Point(*coords) for coords in feature])))```  Polygon Geometry- Consists of at least 3 points and is closed    + ends where the first point begins- You pass in an array and a spatial reference- If you don't provide the last coordinate to close the geometry, arcpy will use the first x/y coordinate```pythonimport arcpyxys = [[5,5], [10,10], [10,5]]array = arcpy.Array([arcpy.Point(*xy) for xy in xys])polygon = arcpy.Polygon(array)```  MutltiPoint Geometry - They are ordered collection of points- Collections or group of x/y locations associated with a single geometry```pythonimport arcpyxys = [[-99,5, 70], [100,-57, 56]]array = arcpy.Array([arcpy.Point(*xy) for coords in xys])mp = arcpy.Multipoint(array)```<jupyter_code>import arcpy
xys = [[5,5], [10,10], [10,5]]
array = arcpy.Array([arcpy.Point(*xy) for xy in xys])
arcpy.Multipoint(array).JSON<jupyter_output><empty_output><jupyter_text>Spatial References- Geographic datasets, such as feature classes, coverages, and rasters, have a spatial reference - The spatial reference defines a dataset's coordinate system, x,y domain, m-domain, and z-domain- The `SpatialReference` object can be created of obtained from existing dataset:    + From `arcpy.SpatialReference`    + From arcpy.da.Describe  Why Are Spatial References Important- Identifies the coordinate systems- Allows data to be in the best projection for the job- Provides information about how the data is represented on Earth    + Cartesian    + Geographic[more information here](https://www.e-education.psu.edu/geog160/node/1914)  Creating Spatial Reference Objects- Many ways to create objects:    + from factory code (4326)    + from projection file (.prj)    + from string ```pythonsr = arcpy.SpatialReference(4326)sr = arcpy.SpatialReference("c:/coordsystems/NAD 1983.prj")wkt = "GEOGCS['GCS_WGS_1984',DATUM['D_WGS_1984',SPHEROID['WGS_1984',6378137.0,298.257223563]],\               PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]];\               -400 -400 1000000000;-100000 10000;-100000 10000;8.98315284119522E-09;\               0.001;0.001;IsHighPrecision"sr = arcpy.SpatialReference()sr.loadFromString(wkt)```  Useful Properties - `factoryCode` - The factory code or well-known ID (WKID) of the spatial reference```python>>> sr = arcpy.da.Describe(fc)['spatialReference']>>> print(sr.factoryCode)32145```- `name` - name of the projection- `type` - The type of the spatial reference- These properties help you when reprojecting or working with mixed spatial references<jupyter_code>import arcpy
for factcode in [4326, 32145]:
    sr = arcpy.SpatialReference(factcode)
    print((sr.name, sr.type, sr.factoryCode))<jupyter_output>('GCS_WGS_1984', 'Geographic', 4326)
('NAD_1983_StatePlane_Vermont_FIPS_4400', 'Projected', 32145)<jupyter_text>Geometries and Spatial References- So far we have create geometries without spatial references```python>>> pt = arcpy.Point(X=34, Y=-74)>>> sr = arcpy.SpatialReference(4326)>>> pt_geom = arcpy.PointGeometry(pt, sr)>>> print(pt_geom.JSON)'{"x":34,"y":-74,"spatialReference":{"wkid":4326,"latestWkid":4326}}'```  Creating Feature Classes- ArcPy's `management` sub-package provides tool to create and modify feature classes- At minimum, always include name, path, spatial reference and geometry type in `CreateFeatureClass`- Names must be **unique**```pythonfc = arcpy.management.CreateFeatureclass(out_name="data.shp",                                         out_path=r"c:\temp",                                         spatial_reference=arcpy.SpatialReference(4326),                                         geometry_type="POINT")[0]```  Ensuring Unique Names- `arcpy.CreateUniqueName` provides a unique name    + if the name exists it adds a number at the end of the name    ```python>>> arcpy.management.CreateFeatureclass(out_name="data.shp",                                         out_path=r"c:\temp",                                         spatial_reference=arcpy.SpatialReference(4326),                                         geometry_type="POINT")[0]>>> out_fc = arcpy.CreateUniqueName(base_name="data.shp",                                   workspace=r"c:\temp")>>> print(out_fc)c:\temp\data0.shp```  Add Field to Feature Class- `AddField` provides way of adding columns to a table, featureclass or raster- Allowed types    + TEXT —Any string of characters.    + FLOAT — Fractional numbers between -3.4E38 and 1.2E38.    + DOUBLE — Fractional numbers between -2.2E308 and 1.8E308.    + SHORT — Whole numbers between -32,768 and 32,767.    + LONG — Whole numbers between -2,147,483,648 and 2,147,483,647.    + DATE —Date and/or time.    + BLOB —Long sequence of binary numbers. You need a custom loader or viewer or a third-party application to load items into a BLOB field or view the contents of a BLOB field.    + RASTER —Raster images. All ArcGIS software-supported raster dataset formats can be stored, but it is highly recommended that only small images be used.    + GUID —Globally unique identifier.```pythonarcpy.management.AddField(in_table=out_fc,                           field_name="DESCRIPTION",                           field_type="TEXT",                           field_length=150)```  Adding Fields to a Feature Class<jupyter_code>out_fc = r"c:\temp\data.shp"
fields = [
    ("FIELDTXT", "TEXT"),
    ("FIELDDBLE", "DOUBLE"),
    ("FIELDINT", "LONG"),
    ("FIELDFLT", "FLOAT")]
for fld in fields:
    arcpy.management.AddField(in_table=out_fc, field_name=fld[0], field_type=fld[1])
[fld.name for fld in arcpy.ListFields(out_fc)]<jupyter_output><empty_output><jupyter_text>Geometries as Inputs/Outputs- Geoprocessing tools allow for direct inputs of Geometries    + support inputs    + support outputs- Substitute geometry for feature classes- Sometime when you need to do a simple operation and not write to disk!<jupyter_code>import arcpy
sr = arcpy.SpatialReference(4326)
xys = [[5,5], [10,10], [10,5]]
array = arcpy.Array([arcpy.Point(*xy) for xy in xys])
ply = arcpy.Polygon(array, sr)

buffer_geom = arcpy.analysis.Buffer(in_features=ply, 
                      buffer_distance_or_field="100 Feet", 
                      out_feature_class=arcpy.Geometry())[0]
buffer_geom<jupyter_output><empty_output><jupyter_text>Geometries as Inputs/Outputs- Geometry as input and Feature class as output```pythonimport osimport arcpyfrom arcpy import envarcpy.management.CopyFeatures(in_features=buffer_geom,                               out_feature_class=os.path.join(env.scratchGDB,                                                              "bufferply"))[0]```  Example: Reading GeoJSON to a Feature Class<jupyter_code>import json, os
import requests
import arcpy
from arcpy import env
from arcpy import da
fc = os.path.join(env.scratchGDB, "alaskaJS")
if arcpy.Exists(fc):
    arcpy.management.Delete(fc)
fc = arcpy.management.CreateFeatureclass(out_path=env.scratchGDB,
                                         out_name="alaskaJS",
                                         geometry_type="POLYGON",
                                         spatial_reference=arcpy.SpatialReference(4326))[0]
arcpy.management.AddField(fc, field_name="STNAME", field_type="TEXT")

with open("./alaska.geojson", 'r') as reader:
    text = reader.read()
    data = json.loads(text)
    with da.InsertCursor(fc, ['SHAPE@', "STNAME"]) as icur:
        for feature in data['features']:
            geom = arcpy.AsShape(feature['geometry']) # Converts GeoJSON to ArcPy Geometry
            NAME = feature['properties']['NAME']
            icur.insertRow([geom, NAME])
print(f'Finished: Inserted {arcpy.GetCount_management(fc)[0]} Rows')<jupyter_output>Finished: Inserted 653 Rows
{'fraction_non_alphanumeric': 0.11430401757115402, 'fraction_numerical': 0.045300631463347674, 'mean_word_length': 3.6680905595899187, 'pattern_counts': {'":': 8, '<': 26, '<?xml version=': 0, '>': 65, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '528769', 'license': 'Apache-2.0', 'n_tokens_mistral': 3640, 'n_tokens_neox': 3229, 'n_words': 943, 'path': 'lecture/Lesson 05/Lesson 05 - ArcPy Working with Geometries.ipynb', 'repo_name': 'shaheen19/Adv_Py_Scripting_for_GIS_Course', 'size': '10927'}