4

I have an arcpy script that dynamically creates a filegeodatabase and its featureclasses from uploaded spatial data, currently point and line features and possibly polygons in the future. I am interested in what is the best way to go about creating a polygon around the entire contents of the gdb.

Ideally, it would be perfect if I there was a way to do minimum boudning geometry on a set of feature classes, or an entire geodatabase, and maybe that is a thing somewhere that I am not seeing.

I have had success just calling that and creating polygons for each feature class, and then take the union of all the polygons for the geodatabase, however as the datasets get large that seems like it wouldn't be a very efficient way of handling it.

Another way I'm looking at right now is getting a list of all the points and doing a bounding geometry algorithm on them, furthermore just getting the min/max xy of each polygon and run it against a list of those.
It just seems like there is a tool or something that I'm not aware of that does this and would be a better way of solving the problem.

4

You could loop through all the feature classes in the gdb and use the minimum bounding geometry gp tool to create convex hull polys in memory and then run a final minimum bounding geometry process on all these polys. This is untested, but something like this may work:

import os, arcpy
def iter_ws(workspace, dataType='Any', ftype='ANY', wildcard='*'):
    '''Iterates through a workspace using arcpy.da.Walk

    valid data types can be found @:
        http://resources.arcgis.com/en/help/main/10.1/index.html#//018w00000023000000

    Required:
    workspace -- workspace to check for features

    Optional:
    dataType -- type of data to search for
    ftype -- feature and raster data types can be further filtered by this parameter
    wildcard -- wildcard for feature names
    '''

    # find top level features and rasters
    for dirpath, dirnames, filenames in arcpy.da.Walk(workspace,
                                                      datatype=dataType,
                                                      type=ftype):
        for name in filenames:
            feature = os.path.join(dirpath, name)
            if wildcard != '*':
                if fnmatch.fnmatch(feature, os.path.join(dirpath, wildcard)):
                    yield feature
            else:
                yield feature

def gdb_bb(gdb, output_polygon):
    polys = []
    for fc in iter_ws(gdb):
        tmp = r'in_memory\{0}_poly'.format(os.path.basename(fc))
        arcpy.MinimumBoundingGeometry_management(fc, tmp, "CONVEX_HULL", "ALL")
        polys.append(tmp)

    # merge polys
    merged = r'in_memory\merged'
    arcpy.Merge_management(polys, merged)

    # run convex hull again to create output
    arcpy.MinimumBoundingGeometry_management(merged, output_polygon, "CONVEX_HULL", "ALL")
    return output_polygon

if __name__ == '__main__':
    gdb = r'path\to\your.gdb'
    final = r'path\to\your.gdb\convex_hull'
    gdb_bb(gdb, final)
  • I should add the "CONVEX_HULL" geometry type can only be used at the ArcInfo license level, but using one of the rectangle options can be used at all license levels. – crmackey Oct 28 '14 at 19:02
  • This is nice. It's more along what I was trying to do in the first place. Can you explain the in memory part? You have a raw string that is a path on disk? Or are you just creating an arbitrary feature class in ram? – branchini Oct 28 '14 at 20:35
  • No problem, saving files "in_memory" creates temporary gdb's in the RAM. It is supposed to be automatically deleted after the script runs. The help docs explain it better than I can: resources.arcgis.com/en/help/main/10.2/index.html#//… – crmackey Oct 28 '14 at 20:48
  • wow... I did not know this was a thing... Before I was just creating things on disk and then using them that way. I imagine this is going to speed up run time a lot for what I'm doing. I can't believe I never knew about this – branchini Oct 28 '14 at 21:19
  • Well I started with the other suggested solution and it was some what working. However I then implemented this and it worked perfectly and I'm going to go with this solution. – branchini Oct 29 '14 at 23:53
5

For a full geodatabase, a quick solution is to create a bounding polygon based on the extents of each feature class. Of course, I assume that all your feature classes are in the same coordinate system.

you can loop on the feature classes of the geodatabase, request the extent and store the min, max values in X and Y. something like below (same for Y)

minX = 1000000000
maxX = 0

for featureClass in featureClasses:
    if (minX > arcpy.describe(featureClass).extent.XMin):
        minX = arcpy.describe(featureClass).extent.XMin
    if (maxX < arcpy.describe(featureClass).extent.XMax):
        maxX = arcpy.describe(featureClass).extent.XMax

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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