Get smallest extent from a list of rasters - different approach

2591
19
Jump to solution
01-22-2016 03:44 AM
Andreas
New Contributor III

Original thread located here: Get smallest extent from a list of rasters

I had issues with that method, if some extents do not overlap, arcgis extent is "empty" while the above minof is (always?) still a rectangle!
In the docs it is said thats minof is the intersection of inputs. But that seems not to be a Intersect_analyst-equivalent. I tried with three extent objects, two do not overlap and one overlaps all other.

Message was edited by: Xander Bakker (branched to new thread)

0 Kudos
1 Solution

Accepted Solutions
XanderBakker
Esri Esteemed Contributor

If the calculation was done by collecting all the minx, miny, maxx and maxy and use the resulting mins and maxs as points to construct the extent, the result will be as you showed in your image. This is however, as you concluded yourself, not the correct result.

Let's take a look at the code below that shows what happens:

import arcpy

def main():
    ext1 = arcpy.Extent(1, 0, 9, 5)
    ext2 = arcpy.Extent(0, 1, 10, 10)
    ext3 = arcpy.Extent(0, 6, 6, 12)

    print "getIntersectingExtent", getIntersectingExtent([ext1, ext2, ext3])
    print "getMinsMaxsExtentsAsExtent", getMinsMaxsExtentsAsExtent([ext1, ext2, ext3])

def getIntersectingExtent(lst):
    ext = lst[0]
    for e in lst[1:]:
        if ext.overlaps(e) or ext.contains(e) or ext.within(e) or ext.equals(e):
            ext = getOverlapExents(ext, e)
        else:
            return None
            break
    return ext

def getOverlapExents(ext1, ext2):
    return getMinsMaxsExtentsAsExtent([ext1, ext2])

def getMinsMaxsExtentsAsExtent(lst):
    xmin = max([e.XMin for e in lst])
    xmax = min([e.XMax for e in lst])
    ymin = max([e.YMin for e in lst])
    ymax = min([e.YMax for e in lst])
    return arcpy.Extent(xmin, ymin, xmax, ymax)

if __name__ == '__main__':
    main()

The result of the code is:

getIntersectingExtent None
getMinsMaxsExtentsAsExtent 1 5 6 6 NaN NaN NaN NaN

Both use the same procedure where the min and max of the extents is determined. However, the first result will test is there is overlap and then determine the minimums and maximums. The second will simply determine the minimums and maximums of the extents and when provided to the arcpy.Extent() method this will correct for minimums being larger than maximums.

View solution in original post

0 Kudos
19 Replies
XanderBakker
Esri Esteemed Contributor

Could you elaborate on what the desired output should be based on the three rasters you mentioned?

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

From environment settings Output Extent (Environment setting)—Help | ArcGIS for Desktop

With intersection of inputs...

Intersection of Inputs—The extent where all input features or rasters overlap (intersect one another). Note that it is possible that none of the features overlap and that a null extent (zero width and height) may result. In such cases, no features will be processed.

XanderBakker
Esri Esteemed Contributor

True, and that's what the script from the original post did. That's why I would like to hear what the desired output should be, to see if something can be created to match that...

0 Kudos
Andreas
New Contributor III

Thank you for your contribution,

I got an extent "between" the non-overlapping rasters, but it should be none, i think.

The Problem araised with a tool that shoud calculate a hexagonal fishnet, where the extent is provided by the user, with an extent parameter in a script tool. Now my question was how to calculate the extent, if the parameter value is MINOF and was glad to see your solution. If i use a tool, like Copy_management and an MINOF in environments extent, the tool creates no output, because the two of three extents do not overlab. But this isn't possible to get with the approach above?

I attached a new sketch to show what i got.

Andreas

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

not sure

yellow blue intersect produces max-X and max-Y for MIN-OF

purplish blue intersect produces min-X and min-Y for MIN-OF

IF min-of is your left-over bit

Now I am wondering if the order affects the results.  overlay blue last...

order as yellow, purple then blue

compare to

blue, then yellow, purple

0 Kudos
Andreas
New Contributor III

Luc Pinner said that max(minx), max(miny), min(maxy), min(maxy) would be the MINOF-extent,

but if you read arcgis-docs it says it would be the "intersection of inputs" where all inputs overlap.

So, if they don't overlap, the extent should be None. But with the calculation above i always get an extent, it can't be "none". I'm looking for a prcedure that gives me the same result as If i use the minof extent in the tool environment (processing extent). But i don't know how to do it.

In the environment settings you can't set an order and if you calculate a min or a max order doesn't matter either. Do you mean arcgis may use an ordered set of extents? Too bad we can't see an output of the processing extent...

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

What I was suggesting is that you try it yourself during the selection process... it may be easier to control the order through scripting... buy you can compare using the procedure I described instead of using all three at once, do the process incrementally and in different orders.

XanderBakker
Esri Esteemed Contributor

If the calculation was done by collecting all the minx, miny, maxx and maxy and use the resulting mins and maxs as points to construct the extent, the result will be as you showed in your image. This is however, as you concluded yourself, not the correct result.

Let's take a look at the code below that shows what happens:

import arcpy

def main():
    ext1 = arcpy.Extent(1, 0, 9, 5)
    ext2 = arcpy.Extent(0, 1, 10, 10)
    ext3 = arcpy.Extent(0, 6, 6, 12)

    print "getIntersectingExtent", getIntersectingExtent([ext1, ext2, ext3])
    print "getMinsMaxsExtentsAsExtent", getMinsMaxsExtentsAsExtent([ext1, ext2, ext3])

def getIntersectingExtent(lst):
    ext = lst[0]
    for e in lst[1:]:
        if ext.overlaps(e) or ext.contains(e) or ext.within(e) or ext.equals(e):
            ext = getOverlapExents(ext, e)
        else:
            return None
            break
    return ext

def getOverlapExents(ext1, ext2):
    return getMinsMaxsExtentsAsExtent([ext1, ext2])

def getMinsMaxsExtentsAsExtent(lst):
    xmin = max([e.XMin for e in lst])
    xmax = min([e.XMax for e in lst])
    ymin = max([e.YMin for e in lst])
    ymax = min([e.YMax for e in lst])
    return arcpy.Extent(xmin, ymin, xmax, ymax)

if __name__ == '__main__':
    main()

The result of the code is:

getIntersectingExtent None
getMinsMaxsExtentsAsExtent 1 5 6 6 NaN NaN NaN NaN

Both use the same procedure where the min and max of the extents is determined. However, the first result will test is there is overlap and then determine the minimums and maximums. The second will simply determine the minimums and maximums of the extents and when provided to the arcpy.Extent() method this will correct for minimums being larger than maximums.

0 Kudos
XanderBakker
Esri Esteemed Contributor

Just noticed that you cannot simply use the arcpy.Extent().overlaps to check for intersection. You need to evaluate contains, within and equals too.

Something like this:

def extentIntersects(ext1, ext2):
    if ext1.overlaps(ext2) or ext1.contains(ext2) or ext1.within(ext2) or ext1.equals(ext2):
        return true
    else:
        return False