Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I have been tasked with creating several hundred maps of properties that intersect a long pipeline. The maps will zoom to the part of the property which shows the intersection. The lengths of pipeline that intersect the properties is highly variable -from two metres to over 16,000 metres. Therefore, each map will be at very different scales.

I am trying to work out a way to automate the updating of a SCALE field for use in data driven pages. I have found that in general, for my maps, there is between a 1:4 to 1:5 ratio between the length of pipe segment to the scale. That is, if the pipe segment is 1100 metres, then a useful scale would be about 1:5000. I would prefer to round the scale up rather than down so that I can see the full feature on the map.

I want to avoid using scales that are not commonly used such as 1:7000 or 1:19,000, for example. I have come up with the following solution for use in the field calculator:

import bisect
def scale(n):
  scaleMult=n*5
  scaleList=[500,1000,1250,1500,2000,2500,4000,5000,7500,10000,12500,15000,20000,25000,30000,40000,50000,75000,100000,150000,200000]
  roundedScale=scaleList[bisect.bisect(scaleList,scaleMult)]
  return roundedScale

The above code multiplies the length by some number (I chose 5) then finds out where in my predefined list of scales it should go and returns the next one higher. The code works pretty well for about 90% of the properties. I played around with the scaleMult variable and multiplied n by a few different values between 4 and 5 but nothing really improved the maps.

I was thinking that there might be a better solution. If the pipe is not very straight and doubles back on itself slightly or has a major bend in it, then the feature didn't fit well on the map. It was usually zoomed in too far.

One idea I had was to use the features bounding box. Maybe there is a relationship between the feature's bounding box area and the scale. But, if the bounding box is long and thin, the scale could be different to a bounding box that was a square of the same area.

Does anyone have any ideas on how to implement such a process?

Are there any better solutions that I'm not thinking of?

Looking for solutions in ArcGIS 10.1 and 10.2.

I'll happily edit the question if more clarification is required.

share|improve this question
    
As a thought have you considered creating some sort of exceptions list? Perhaps a Python dictionary with LotPlan as key and SuitableScale as value and then use algorithm if LotPlan not in dictionary, otherwise use SuitableScale found there. –  PolyGeo Nov 15 '13 at 0:21
    
@PolyGeo, I'm not sure that would work. It's not based on LotPlan but on the length of pipe that intersects the lot. It could intersect on a small corner of a very large property. Also, sometimes the pipe can enter then exit, then reenter the property in a completely different place. –  Fezter Nov 15 '13 at 0:27
    
Perhaps a pipe segment ID is available to use in a similar fashion. –  PolyGeo Nov 15 '13 at 1:43
    
I'm not sure I've explained myself fully. Using your method, I would still have to manually figure out the ideal scale for each pipe segment (or property). I'm looking for a way to automatically generate an ideal scale for each feature. –  Fezter Nov 15 '13 at 3:14
    
I've been working on a similar process/solution. You need to compare the size and trending direction of the features bounding box to that of your data frame (in layout view). I've got some code that is close, which I will post when complete. –  RyanDalton Nov 15 '13 at 4:09

1 Answer 1

I would set up the DDP using the pipeline as the ddp layer. In the Python script, iterate over the pages and check the data frame scale. Using some conditional logic, you can calculate what the scale for that map should be, and then export.

Here is part of a script I have used in the past:

import arcpy
mxd = arcpy.mapping.MapDocument(r"C:\MyMap.mxd")
df = arcpy.mapping.ListDataFrames(mxd)[0]
for i in range(0, mxd.dataDrivenPages.pageCount + 1):
    mxd.dataDrivenPages.currentPageID = i
    if df.scale < 1500:
        df.scale = 1500
    #do more things and export

In your case, you could use if...elif logic to cover all your scales you've included in your scale list (since you have worked them out already), or you could do some calculations to round the number up to the nearest 500 or 1000 or whatever you want.

This method calculates the scale each time the script is run, so if you are going to run it multiple times but don't envision the pipeline changing (though other layout elements might), you may need to add a field as suggested and use an UpdateCursor to save these scale values into it. You could then export the data driven pages from ArcMap using the scale field for your extent

share|improve this answer
    
This is a good solution. I could probably merge it with my solution of using the bisect module. –  Fezter Nov 15 '13 at 10:24

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.