I have a street shapefile with information about the street name, house number from / to on the left side and house number from / to on the right side.
My aim is to create a point shapefile that visualizes all houses along the streets. A first prototype is already implemented. With a Search-cursor I am reading out the total number of houses by building the range by using the paramaters house number from / to on the left side and house number from / to on the right side. The total amount is divided by the length of the street so that I have a value that show me in which distance I have to place the points along the line to map all houses.
The result is that all house numbers are placed like a string of pearls.
Is there a way to place the numbers with an specific offset along the line?
The script is written in python using arcpy and ArcGIS 10.1 SP1.
Thanks!
3 Answers 3
In case this is helpful to others, i was able to create the following python code using arcpy which will place points at a specified interval based on an input line feature layer.
import arcpy
line_lyr = 'my_line'
pt_lyr = "my_point"
interval = 200
insertCursor = arcpy.da.InsertCursor(pt_lyr, ["SHAPE@XY"]) # this is the pre-existing pt feature class
with arcpy.da.SearchCursor(line_lyr, ['OID@','SHAPE@','NAME']) as searchCursor: # this is the line feature on which the points will be based
for row in searchCursor:
lengthLine = round(row[1].length) # grab the length of the line feature, i'm using round() here to avoid weird rounding errors that prevent the numberOfPositions from being determined
if int(lengthLine % interval) == 0:
numberOfPositions = int(lengthLine // interval) - 1
else:
numberOfPositions = int(lengthLine // interval)
print "lengthLine", lengthLine
print "numberOfPositions", numberOfPositions
if numberOfPositions > 0: # > 0 b/c we don't want to add a point to a line feature that is less than our interval
for i in range(numberOfPositions): # using range, allows us to not have to worry about
distance = (i + 1) * interval
xPoint = row[1].positionAlongLine(distance).firstPoint.X
yPoint = row[1].positionAlongLine(distance).firstPoint.Y
xy = (xPoint, yPoint)
insertCursor.insertRow([xy])
I would use Geocoding tools. Geocoding will help you to solve 2 problems:
- Side offset (the problem in your question)
- End offset (a new problem that you'll have if you solved Side offset)
If you solve side offset your map will look like this: enter image description here
But near street intersections you will get this new problem: enter image description here
To solve this, you will need a second offset – the "end offset". Then your map will look like this: enter image description here
In ArcGIS you can specify Side offset and End offset in Geocoding options properties.
I suggest that you try this approach:
- Write a python script to create a table will all addresses. The street shapefile serves as your source file for this.
- Use the table from step 1 to create Points for all addresses. See ArcGIS help About geocoding a table of addresses.
-
(+1) on the assumption that the asker will be happy to abandon the work done so far - I had been thinking he had bypassed Geocoding as being unsuitable for his address but maybe he just overlooked it.2013年07月18日 09:36:33 +00:00Commented Jul 18, 2013 at 9:36
To do this I would look at Linear Referencing, because once you have a Route Event Layer of type POINT for your addresses, you should be able to use label offsets to place your event points.
I would recommend taking a quick look at this part of the Linear Referencing Tutorial to see if it sounds like what you are after. If it does, prototype it through the ArcMap GUI, and then start on the ArcPy code which I think should be straight forward.
The key concept is that addresses can be considered as point events referenced along a route representing the street.