POST
|
This question is back to basics; I looked around for an answer or a clue and I can't find what I'm looking for. I'm stuck. I've got 3 variables with assigned string values (shapefile paths) and I am running them through a loop to check that their projected coordinate systems (PCS) are the same as my DEM's PCS. I want the code to check if they're the same, and if not, I want to project the file and reassign the projected file path to the original variable. This is my code: print("Verifying that coordinate systems are the same...")
InSHP = [outline, DA, soil]
DEMSR = arcpy.Describe(DEM).spatialReference.PCSCode
for i, l in enumerate(InSHP):
print InSHP
sr = arcpy.Describe(l).spatialReference.PCScode
if sr != DEMSR:
l = arcpy.Project_management(l, l[:-4] + "PRJ.shp", DEMSR)
InSHP = l
print InSHP
print outline print InSHP produces the modified file path but print outline does not. So, l = the projected shapefile but the l doesn't automatically connect the original variable name (outline) to the new path. I was initially expecting the program to automatically deduce that l = new path = outline, which was kind of stupid of me to think in retrospect. Now I explicitly know that l only refers to the entry in the list and is in no way connected to the original variable aside from having the same starting values. Is there a way to automate this sort of assignment or am I doomed to adding the following at the end of my code? outline = InSHP[0]
DA = InSHP[1]
soil = InSHP[2] I guess it's not a big deal because there's only 3 of them but what if I need to check more inputs? As a side question, this loop tells me that my soils file does not have a PCS, but when I look at the file properties in GIS or Catalog, it does have a PCS. Any idea why that's happening? EDIT: Ugh. Adding those next 3 lines at the end didn't actually accomplish what I wanted it to accomplish. I'm so used to working with cursors and GIS tables that my plain list skills are lacking. :S EDIT 2: Okay I got my list to update using the enumerate function and I updated my code accordingly. My original question(s) still stand, though. Is there a way to assign the new values to the original variables names without having to explicitly type the variable names again? I'm starting to think there isn't but I already posted this and I'm going to keep it here in case any other novice has this same problem.
... View more
06-10-2015
07:40 AM
|
0
|
8
|
5738
|
POST
|
I meant setting my environments so the output CS is the same as my DEM CS, so that the output of any tool results in PCS. But, it probably is better to write a code block that checks projections before the code actually starts. Thanks for the tip!
... View more
06-09-2015
11:35 AM
|
2
|
1
|
1872
|
POST
|
Would it be just as good to set my output CS to the projected system my DEM is in and have GIS take care of the conversion automatically?
... View more
06-09-2015
11:22 AM
|
0
|
3
|
1872
|
POST
|
All I had to do was set an output coordinate system and it worked! Yay! arcpy.env.outputCoordinateSystem = arcpy.Describe(DEM).spatialReference Of course, now I'm getting a different error but hopefully it's unrelated to this one.
... View more
06-09-2015
11:21 AM
|
0
|
0
|
1872
|
POST
|
:U OH NO!! My DEM is a projected coordinate system (NAD 1983 HARN VA State Plane South) but my buffer is in a GCS, NAD 1983 HARN. How do I resolve this discrepancy in Python?
... View more
06-09-2015
11:12 AM
|
0
|
6
|
1872
|
POST
|
I've been developing my program with just one dataset and I got all the bugs worked out from that one dataset. Now, I am trying it on some other datasets to make sure everything is working as expected. I am having a problem in the setting-up-the-environments stage of my program. The user inputs a polygon shapefile that contains a polygon representing the parcel outline. This polygon is used to create a mask for future raster calculations. The basic outline of this part of the program is as follows: Buffer the outline polygon by 50 ft Convert the buffered polygon into a raster Set the raster as the mask and the snapraster for the remainder of the program An empty raster is created when converting the buffered polygon to a raster. I tried doing it manually in GIS and had the same problem. I added an integer field to my buffered shapefile and converted to a raster based on that integer field (rather than the ID or FID which were both 0.) That didn't fix it. After setting the processing extent to the same extent as my DEM, it worked. I made those changes to my code and it still is not producing the expected results. It's not giving me an error, but it tells me that the raster is empty and then keeps running through my code. I've exhausted my troubleshooting abilities. I also want to repeat: it works when I do it by hand in GIS but it isn't working via code for some reason. My code is printing out the following: Preparing necessary files... Checking for and creating output folders for GIS files... Checking for and creating output space for tables... Setting cell size to DEM cell size: 5.0 ft... Creating an environment mask from the site outline shapefile... All cells in grid k:\gradwork\gis\colleg~1\cp\scratch\rastermask have NODATA value. VAT will not be built. (VatBldNew) My code is below. Line 84 is where things are going wrong. #### _______________IMPORT MODULES_________________###
print("Preparing necessary files...")
import os
import arcpy
import copy
### ______________INPUT FILES___________________###
outline = r"K:\GradWork\GIS\CollegePark\CP_outline.shp"
DA = r"K:\GradWork\GIS\CollegePark\CPDrainage.shp"
DAID = "Id" # field in DA shapefile where unique DA values exist
soil = r"C:\Users\Rachael J\Documents\GradWork\Project Files\BMPGIS\soils\VB_Soils.shp"
WTin = r"K:\GradWork\GIS\CollegePark\CPGW_adj1"
DEMin = r"K:\GradWork\GIS\CollegePark\cpelev"
MapLoc = r"K:\GradWork\GIS\CollegePark\CP.mxd"
WT = arcpy.Raster(WTin)
DEM = arcpy.Raster(DEMin)
### ________________SET ENVIRONMENTS__________________###
# Check out extension and overwrite outputs
arcpy.CheckOutExtension("spatial")
arcpy.env.overwriteOutput = True
# Set Map Document
mxd = arcpy.mapping.MapDocument(MapLoc)
# Create project folder and set workspace
print("Checking for and creating output folders for GIS files...")
WorkPath = MapLoc[:-4]
if not os.path.exists(WorkPath):
os.makedirs(WorkPath)
arcpy.env.workspace = WorkPath
# Create scratch workspace
ScratchPath = str(WorkPath) + r"\scratch"
if not os.path.exists(ScratchPath):
os.makedirs(ScratchPath)
arcpy.env.scratchWorkspace = ScratchPath
# Create GDB
path, filename = os.path.split(MapLoc)
GDB = filename[:-4] + ".gdb"
GDBpath = MapLoc[:-4] + ".gdb"
if not os.path.exists(GDBpath):
arcpy.CreateFileGDB_management(path, GDB)
# Create output table folder if it does not exist and create project folder
print("Checking for and creating output space for tables...")
TabPath = r"C:\outputtable" "\\"
ProjFolder = TabPath + filename[:-4]
if not os.path.exists(TabPath):
os.makedirs(TabPath)
if not os.path.exists(ProjFolder):
os.makedirs(ProjFolder)
### _____________SET PROCESSING EXTENTS____________ ###
# Set cell size
description = arcpy.Describe(DEM)
cellsize = description.children[0].meanCellHeight
print("Setting cell size to DEM cell size: " + str(cellsize) + " ft...")
arcpy.env.cellSize = cellsize
arcpy.env.extent = arcpy.Describe(DEM).extent
# Create buffer around outline to use as mask
# Buffer distance is in feet
print("Creating an environment mask from the site outline shapefile...")
maskshp = arcpy.Buffer_analysis(outline, ScratchPath + r"\outline_buff", "50 Feet", "", "", "ALL",)
arcpy.AddField_management(maskshp, "RID", "SHORT")
with arcpy.da.UpdateCursor(maskshp, ["RID"]) as cursor:
for row in cursor:
row[0] = 8
cursor.updateRow(row)
# Convert buffer to raster
mask = arcpy.Raster(arcpy.PolygonToRaster_conversion(maskshp, "RID", ScratchPath + r"\rastermask"))
mask.save(ScratchPath + r"\rastermask")
# Set raster mask and snap raster
print("Setting raster mask and snap raster for project...")
arcpy.env.mask = mask
arcpy.env.snapRaster = mask EDIT: Changing line 69 to "arcpy.env.extent = DEM.extent" did not solve the problem. EDIT 2: My files aren't in the same coordinate system!
... View more
06-09-2015
10:47 AM
|
0
|
8
|
5760
|
POST
|
I was thinking about doing something like that while I was typing up my response to you, actually. I'll see how well it works soon!
... View more
06-05-2015
12:31 PM
|
0
|
0
|
603
|
POST
|
I need to create a raster that has values between -0.5 and +0.5 and adjacent cells in that raster are more similar to nearby cells than they are to further cells. Each time I generate such a grid, the value at a particular grid point will vary randomly. Thus, I need a random grid that is spatially correlated, something like that described on this page: Generating spatially correlated random fields with R – Santiago Beguería
... View more
06-05-2015
11:32 AM
|
0
|
2
|
603
|
POST
|
I want to run a Monte Carlo uncertainty analysis in a program I am creating. I've got the framework for my Monte Carlo analysis set up and it runs fine except for one thing: my method of variation. My method of random variation so far is to create a Normal Raster (sa.CreateNormalRaster) with the cellsize and extent of my existing DEM, adjust the Normal Raster values so they fall within the RMSE of my DEM (+/- 0.5 ft), and then add that adjusted Normal Raster to my existing DEM. My DEM has a 5.0 ft resolution and adjacent cells vary by less than 0.2 ft, usually; the terrain is very flat. The potential for adjacent cells to vary by up to 1 ft is unacceptable for my purposes. I need to somehow spatially correlate these random values so I can apply them to my DEM in a way that makes sense. I know this is a somewhat tall order given the complexity of the published literature on this topic. I don't necessarily need to correlate the random values with the spatial covariance of the DEM at this point in time (although that would be preferred). It's my understanding that I will very likely need to bring in another program (like R) to do the latter. For now, I would ideally like to do something within Python.
... View more
06-05-2015
10:38 AM
|
0
|
4
|
3898
|
POST
|
That was certainly the problem! I modified the code with the copy package so BMP = copy.deepcopy(D) and the problem resolved. Thanks.
... View more
05-20-2015
02:36 PM
|
0
|
0
|
886
|
POST
|
I am comparing the values in one table to the values in another table. I converted the values of one table into a dictionary to avoid using nested cursors. Ultimately, I want to create a table of items that pass each comparison test. I did another version of this where I have separate tables for each area I am testing, start with a full table, and remove rows from the table as each row fails a test. This results in many tables, which is fine for a handful of areas but messy for more than a few. I am trying to build a version that generates all area outputs in the same table. I think it is easier to keep track of those that fail tests than those that pass. I copy the main dictionary, D, to a new dictionary. I create a blank dictionary for the failed tests. Each time something fails a test, I record its key into the Failed Test dictionary and store the reason for failure as a string value. For subsequent tests, if the key already exists in the Failed test dictionary, I add on to the existing value as a pseudo-list to prevent test failures from being overwritten. When all tests are complete, I want to compare the keys in the Failed Test dictionary to the copy of D. If the keys are a match, I want that key and it's associated value removed from the copy of D. What should remain in the copy of D are the BMPs that pass all 4 tests. Then I want to use the values stored in the copy of D to write to a table. Maybe this logic is all sorts of messed up and there's a better way to do it. I am open to suggestions. I have been playing with this code for a while to figure out what the problem is and it seems I have found the first source of error in my code. There appears to be a problem with copying the dictionary, D. Here's the code I have so far. It is missing the write-to-table part because I am not getting the outputs I would expect. print("Comparing site values to constraints...")
# Compare the lumped parameters to the constraint dictionary
for row in arcpy.da.SearchCursor(combo_table, ["DARAS", "HSG", "MEDSLOPE", "MEDWT"]):
BMP = {}
# Temporarily store the area of each DA for later comparison
for r in arcpy.da.SearchCursor(DA_area, [DAID, "SUM_AREA"]):
# NOTE: THE DAID/DARAS MISMATCH COULD BE A PROBLEM LATER. NEED TO TEST.
if r[0] == row[0]:
totalArea = r[1]
# Duplicate criteria dictionary that can be amended throughout the loop
print D
BMP = D
print D
# Initialize empty dictionary to store BMPs that fail each test
NoBMP = {}
# Compare lumped values in each DA/HSG pair to those in the constraint table
print(row[0], row[1])
for k, v in D.items():
# Test if soil type is incorrect for each BMP
if row[1] not in v:
# Add failed BMP to the failed BMP dictionary, NoBMP
NoBMP = "Soil Type Mismatch"
# Compare keys in BMP and NoBMP dictionaries. Remove matching pairs from the BMP dictionary.
for key in BMP.keys():
if key in NoBMP.keys():
del BMP[key] The main takeaway from the following output information is that D changes sizes from one iteration of the Cursor to the next iteration of the Cursor; D does not change size in future iterations of the loop. I think it has something to do with me changing the size of BMP at the end of the code by deleting the matching keys. The keys that are removed are the keys that do not show up in the next iteration. However, I reinitialize BMP as a blank dictionary at the beginning of the Cursor, so I am not sure what else to do. I have also tried BMP = dict() to reinitialize and gotten the same result. Comparing site values to constraints... {u'WPGW1': u'C,D', u'WPGW2': u'C,D', u'VFA': u'A', u'SDCD': u'C,D', u'BRE2': u'A,B,C,D', u'BRE1': u'A,B,C,D', u'SDAB': u'A,B', u'EDP2': u'A,B,C,D', u'WP1': u'C,D', u'CW1': u'C,D', u'CW2': u'C,D', u'DS2': u'A,B,C,D', u'DS1': u'A,B,C,D', u'GCCD': u'C,D', u'F2': u'A,B,C,D', u'F1': u'A,B,C,D', u'CAAB': u'A,B', u'WP2': u'C,D', u'GCAB': u'A,B', u'CACD': u'C,D', u'VFSA': u'B,C,D', u'SI2': u'A,B', u'SI1': u'A,B', u'EDP1': u'A,B,C,D', u'SDSA': u'C,D', u'WS1': u'C,D', u'CI2': u'A,B', u'CI1': u'A,B', u'WS2': u'C,D', u'GCSA': u'C,D', u'MI1': u'A,B', u'MI2': u'A,B'} {u'WPGW1': u'C,D', u'WPGW2': u'C,D', u'VFA': u'A', u'SDCD': u'C,D', u'BRE2': u'A,B,C,D', u'BRE1': u'A,B,C,D', u'SDAB': u'A,B', u'EDP2': u'A,B,C,D', u'WP1': u'C,D', u'CW1': u'C,D', u'CW2': u'C,D', u'DS2': u'A,B,C,D', u'DS1': u'A,B,C,D', u'GCCD': u'C,D', u'F2': u'A,B,C,D', u'F1': u'A,B,C,D', u'CAAB': u'A,B', u'WP2': u'C,D', u'GCAB': u'A,B', u'CACD': u'C,D', u'VFSA': u'B,C,D', u'SI2': u'A,B', u'SI1': u'A,B', u'EDP1': u'A,B,C,D', u'SDSA': u'C,D', u'WS1': u'C,D', u'CI2': u'A,B', u'CI1': u'A,B', u'WS2': u'C,D', u'GCSA': u'C,D', u'MI1': u'A,B', u'MI2': u'A,B'} (1, u'D') {u'WPGW1': u'C,D', u'WPGW2': u'C,D', u'SDCD': u'C,D', u'BRE2': u'A,B,C,D', u'BRE1': u'A,B,C,D', u'EDP2': u'A,B,C,D', u'WP1': u'C,D', u'CW1': u'C,D', u'CW2': u'C,D', u'DS2': u'A,B,C,D', u'DS1': u'A,B,C,D', u'GCCD': u'C,D', u'F2': u'A,B,C,D', u'F1': u'A,B,C,D', u'WP2': u'C,D', u'CACD': u'C,D', u'VFSA': u'B,C,D', u'EDP1': u'A,B,C,D', u'SDSA': u'C,D', u'WS1': u'C,D', u'WS2': u'C,D', u'GCSA': u'C,D'} {u'WPGW1': u'C,D', u'WPGW2': u'C,D', u'SDCD': u'C,D', u'BRE2': u'A,B,C,D', u'BRE1': u'A,B,C,D', u'EDP2': u'A,B,C,D', u'WP1': u'C,D', u'CW1': u'C,D', u'CW2': u'C,D', u'DS2': u'A,B,C,D', u'DS1': u'A,B,C,D', u'GCCD': u'C,D', u'F2': u'A,B,C,D', u'F1': u'A,B,C,D', u'WP2': u'C,D', u'CACD': u'C,D', u'VFSA': u'B,C,D', u'EDP1': u'A,B,C,D', u'SDSA': u'C,D', u'WS1': u'C,D', u'WS2': u'C,D', u'GCSA': u'C,D'} (2, u'D')
... View more
05-20-2015
12:52 PM
|
0
|
2
|
4155
|
POST
|
I figured it out in the mean time, but thank you for your response nonetheless! In case any one else new is having the same problem I am: This is how I built the dictionary with the lists as values: # Convert Excel constraint file to GIS table
compare = arcpy.ExcelToTable_conversion(CRIT, ProjFolder + r"\constraints")
fields = ["Rowid", "CODE", "SOIL", "MAX_SLOPE", "MIN_CDA", "MAX_CDA", "WT_SEP", "WT_RELAX",
"COAST_SEP", "MIN_DEPTH", "DEPTH_RELA", "COAST_MIN_", "BMP", "MOD"]
Fields = [f.name for f in arcpy.ListFields(compare)]
# Create dictionary from criteria table
D = {r[1]:(r[2:]) for r in arcpy.da.SearchCursor(compare, Fields)} The problems I was having involved trying to call the individual entries from the value list. The first problem I had was with the following: for r in 😧 if "A" not in r[0]: print r It would only print the key. Print r[0] printed the first letter. I couldn't seem to access the value, only the key. But I found out that it's because "for r in D" is the same as "for r in D.keys()", so it was only looking at the keys. So when I loop, I have to do "for k, v in D.iteritems()" or just D.items() depending on the version I'm using. The following code accesses the individual items stored in the value lists: for k, v in D.iteritems():
if "A" not in v[6]:
print v[6]
... View more
05-18-2015
10:16 AM
|
2
|
1
|
1238
|
POST
|
I currently have a nested cursor that I need to convert to one Cursor and one dictionary (or series of dictionaries) to improve performance and get a more desirable output. I am a novice at Python coding and I am trying to understand Dictionaries. I found that I can store a list as a dictionary value and I can call the individual entry in the value list. For example, if D is my dictionary with keys key1 through key15 and each key is associated with a list or tuple of 5 entries for its corresponding value. (key12 : [Name, 10, 25, 0, ABCD]). Maybe that notation isn't 100% correct but you get the idea, hopefully. I can call the individual entry in the list by D["key12"][4] which will return ABCD. I have found problems when trying to iterate through these kinds of dictionaries though. Is there a way to access the individual entries in the list/tuple during iteration or am I better off with 5 different dictionaries--one for each category in the list? I actually have to step away from the computer so it may be a bit before I can get back to answer any questions. I apologize. Edit: Grammar.
... View more
05-18-2015
08:23 AM
|
0
|
3
|
5168
|
POST
|
Oh no... I wish I could delete stuff from here so I can hide my shame. I changed the operator at one point and it wasn't updating anything because there wasn't anything to update. :X The main IF statement was always false. Sorry for wasting your time, everyone.
... View more
04-22-2015
10:41 AM
|
0
|
1
|
533
|
POST
|
I've tried moving it all around and I did it again to be sure. Still nothing. If it needs to be on the same level of indentation as the elif statement above it, it's in the right spot.
... View more
04-22-2015
10:34 AM
|
0
|
0
|
533
|
Title | Kudos | Posted |
---|---|---|
1 | 06-09-2017 09:27 AM | |
1 | 06-10-2015 09:02 AM | |
1 | 04-21-2015 06:57 AM | |
2 | 08-19-2015 08:14 AM | |
2 | 06-09-2015 11:35 AM |
Online Status |
Offline
|
Date Last Visited |
11-11-2020
02:23 AM
|