Select to view content in your preferred language

Skyline Graph with multiple observer points

1629
10
02-06-2013 08:20 AM
KellyMaloney
New Contributor II
Hi all,

I have ~2000 observer points and associated skylines created from the Skyline tool.  I wish to use the skyline graph tool to estimate the visibility ratio for each of these points.  However when I run the tool it only provides output for the first observer point.  Is this a limitation to the skyline graph tool?  I also would like to eventually export a table with visibility ratios for all 2000 points.  Any thoughts/advice?

Thanks,
Kelly
Tags (1)
10 Replies
AdamHanna
New Contributor II
Hi Kelly,

I'm having the same problem. Did you ever find a fix?
AdamHanna
New Contributor II
I believe I may have found a workaround, but it's time consuming:

  1. Convert the sklyine polylines to points (convert vertices to points)

  2. Add X, Y and Z data to said points

  3. Calculate Azimuths and Zeniths from the XYZ data and the OID XYZ data


Would really love for the Skyline Graph to be able to handle multiple observer points.....
0 Kudos
KellyMaloney
New Contributor II
Hi Adam,

I hope your work-around did what you needed.  I actually worked with a python coder who created the following script.  This worked perfect and gave me my needed values in a stand-alone csv file. Hope it works for you.

-Kelly

import os

import arcpy
from arcpy import env
arcpy.env.overwriteOutput = True
# Obtain a license for the ArcGIS 3D Analyst extension
arcpy.CheckOutExtension('3D')

# Set local variables
outLocation = r"C:\Users\Desktop\Topographic_shade\Topographic_shade"
inputDataLocation = r"C:\Users\Desktop\Topographic_shade\Topographic_shade"

points = "DR_CenterLine_Dissolve_pointsZ2Da_elev3Dt.shp" 
lines = "DR_CenterLine_Dissolve_pointsZ2Da_elev3D_skyline_originalDEMb.shp"

pointsFile = os.path.join(inputDataLocation, points)
linesFile = os.path.join(inputDataLocation, lines)

# Set environment settings
env.workspace = outLocation

# Process: Create the empty table
outputFName = os.path.join(outLocation, "Shade_original_DEM.csv")
outputFile = open(outputFName, "w")

outputFile.write("ID,PercentOpenSky,PercentShade,MeanHorizAng,MeanZenithAng\n")

fcCursor = arcpy.SearchCursor(pointsFile)
for row in fcCursor:
    print(row)
    #create a temp shapefile with just one of our points
    whereClause = '"FID" = ' + str(row.FID)
    tmpSinglePointShp = os.path.join(outLocation, str(row.FID) + ".shp")
    arcpy.Select_analysis(pointsFile, tmpSinglePointShp, whereClause)
    tmpSingleLineShp = os.path.join(outLocation, "sky" + str(row.FID) + ".shp")
    arcpy.Select_analysis(linesFile, tmpSingleLineShp, whereClause)
    skyCursor = arcpy.SearchCursor(tmpSingleLineShp, "", "", "Length", "")
       
    for rows in skyCursor:
        value = rows.getValue("Length")
        if  value == 0:
            answerPercent = "NA"
            Shade = "NA"
            aveHoriz = "NA"
            aveZenith = "NA"
            outputFile.write(str(row.FID) + "," + str(answerPercent) + "," + str(Shade) + "," + str(aveHoriz) + "," + str(aveZenith) + "\n")

            arcpy.Delete_management(tmpSinglePointShp)
            arcpy.Delete_management(tmpSingleLineShp)
            print(str(row.FID) + "," + str(answerPercent) + "," + str(Shade) + "," + str(aveHoriz) + "," + str(aveZenith) + "\n")
        else:

            #run the skylineGraph on temp output file
            tmpSinglePointOutTbl = os.path.join(outLocation, "t" + str(row.FID) + ".dbf")
            arcpy.SkylineGraph_3d(tmpSinglePointShp, tmpSingleLineShp, 0, "ADDITIONAL_FIELDS", tmpSinglePointOutTbl)
    
            #manually calculate the average of the two fields we are interested in
            count = 0
            horizAngSum = 0
            zenithAngSum = 0
            for outputRow in arcpy.SearchCursor(tmpSinglePointOutTbl):
                horizAngSum += outputRow.HORIZ_ANG
                zenithAngSum += outputRow.ZENITH_ANG
                count += 1
   
            aveHoriz = horizAngSum / count
            aveZenith = zenithAngSum / count
   
            #this next section parses out their printed output and stores the 'Percent of sky in our CSV'
            msgText = arcpy.GetMessages()
            for line in msgText.split("\n"):
                if line.startswith("Percent of sky visible above a base vertical angle"):
                    answerPercent = line.split()[-1][:-1]
                    Shade = 100 - float(answerPercent)
   
            #write out the calculated answers to our CSV
            #outputFile.write(str(row.FID) + "," + str(answerPercent) + "," + str(aveHoriz) + "," + str(aveZenith) + "\n")
            outputFile.write(str(row.FID) + "," + str(answerPercent) + "," + str(Shade) + "," + str(aveHoriz) + "," + str(aveZenith) + "\n")

            arcpy.Delete_management(tmpSinglePointShp)
            arcpy.Delete_management(tmpSingleLineShp)
            arcpy.Delete_management(tmpSinglePointOutTbl)
            #print(str(row.FID) + "," + str(answerPercent) + "," + str(aveHoriz) + "," + str(aveZenith) + "\n")
            print(str(row.FID) + "," + str(answerPercent) + "," + str(Shade) + "," + str(aveHoriz) + "," + str(aveZenith) + "\n")
   
outputFile.close()
0 Kudos
JanetWong
New Contributor

Hi Kelly, 

I'm encountering the same problem. May I ask what is 'lines' in line 11 refers to? Is it referring to the lines generated by the tool 'Skyline'? But I have more than 9,000 points, it is difficult to generate the skyline...

0 Kudos
AdamHanna
New Contributor II
Hey Kelly,

This is great, thanks! However, it appears that when you copy/pasted, all of the indentations were removed from the original python code? Python is very dependent on proper indentations. Would you mind uploading the .py? Or, maybe there's another way to paste the code and keep the indents in tact?
0 Kudos
KellyMaloney
New Contributor II
Hi Adam,

Sorry about that.  I most often use R, so I forget about the indentation issue with python.  See the attached python script.

Kelly
0 Kudos
AdamHanna
New Contributor II
You just saved me a whole lot of work, thanks!
0 Kudos
rosalindkennerley
New Contributor
Hi Adam,
Were you able to get the python code to successfully work with your data set? I have tried applying it to my own data and am getting error messages after the table has been created and the first lot of temporary shape files have been created.

Cheers,
Ros
0 Kudos
JonathanGillespie
New Contributor II
Hi Adam,
Were you able to get the python code to successfully work with your data set? I have tried applying it to my own data and am getting error messages after the table has been created and the first lot of temporary shape files have been created.

Cheers,
Ros


Hi Ros

I may or may not be correct  here (very new to python) but I was trying to use the same script and found the same issue.  I believe it can be resolved by changing the line

skyCursor = arcpy.SearchCursor(tmpSingleLineShp, "", "", "Length", "")

to

skyCursor = arcpy.SearchCursor(tmpSingleLineShp, "", "", "Shape_Leng", "")

It seems to work with the data points that I'm using (only two of them for the time-being).

If anyone can shed any light whether this is indeed the correct solution I would be grateful.  As I said above - very new to Python!

Jonathan
0 Kudos