2. Analysis Overview
January 1st, 2014 -- two-year moratorium on
newcomers to the market on
December 2016, the moratorium was extended an
additional 120 days while City Council further
considered policy and fully assessed the marijuana
industry’s impact on the city and communities.
How many more stores will fit inside the city?
Nobody really understood the situation on the ground.
3. Presentation Overview
- Not really about
marijuana,
- but GIS spatial allocation
methods and Python
- Analysis Overview
- Two-Phase Approach
- Where are eligible locations
- How many will fit?
4. Analysis Overview
Tasked to find the total number of centers or stores
that could fit inside the City and County of Denver
• Applied quantitative GIS techniques to find eligible land
– existing store and center locations
– existing pending store and center application locations
– the current zoning regulations and licensing requirements
• Did not consider qualitative data
– Did not use non-numerical information (i.e., conversations, interviews, visual interpretation)
– Did not consider any market conditions
– Did not take into consideration the current land tenant or owner
• Created an automated and scripted process that populates the
map with eligible locations.
– All candidate facilities meet current regulations.
5. Analysis Criteria
Retail Marijuana Stores and Medical Marijuana Centers cannot be located
1. In any residential zone district as defined by the zoning code of the city
2. In any MS-2, MS-2x, MX-2, MX-2A or MX-2x zone district as defined by the zoning code of the city.
3. In any location where retail sales are prohibited by the zoning code or by any ordinance governing a
Planned Unit Development (PUD).
4. Within one thousand (1,000) feet of any school.
– Using the nearest property line of the land used for school to the nearest portion of the building
in which the store or center is located.
5. Within one thousand (1,000) feet of any other retail marijuana store or medical marijuana center.
– Using the nearest portion of the building in which one store or center is located to the nearest
portion of the building in which the other store or center is located.
6. Within one thousand (1,000) feet of any child care establishment or alcohol or drug treatment
facility.
– Using the nearest property line of the land used for the child care establishment or alcohol or
drug treatment facility to the nearest portion of the property upon which the store or center is
proposed to be located.
6. Assumptions
– Planned Urban Developments (PUDs), Zone District I-B, and Non-Residential Former
Chapter 59 Zones require additional site review. The analysis treats them equal to other
eligible land
– Eligible land less than 11,294.81 sq ft is not included in the analysis
– Schools, childcare centers, and treatment centers that exist outside the city limits of
Denver are not included in this analysis
– Alcohol and Drug Treatment Centers data obtained from the Colorado Dept. of Human
Services and has not been fully vetted by the city.
– Water and Right-Of-Way eliminated from eligible area
– Certain criteria call for a positive spatial match with a building or a parcel. However, if no
positive match can be made, the geocoded point is used.
Positive Match Unsuccessful Match
7. Assumptions
Child Care and Treatment Centers
Using the nearest property line of the land used for the child care establishment or
alcohol or drug treatment facility to the nearest portion of the property upon which
the store or center is proposed to be located.
If the buffer intersects
the parcel, whole
parcel is disqualified
9. Eligible Land Results
Step 1:
Use criteria
to find all
eligible land
Step 2:
Create a
process to
find the
total
number of
eligible
locations
10. Additional Assumptions
Placing Random points on the map
– A point has no mass
– A dispensary does have mass. It is a real place on earth.
– Random points assume a store size of 1,018 sq ft.
– The store is circular
Assumed Store Size Buffer
11. Analysis Problems
Find the Total Eligible Area 1,000 sq ft = Answer?
1,000 ft
100 Stores
Reality is not made of nice tidy boxes
12. Problem Solving
Pros
You can set a distance requirement.
Cons
User asked to input the number ->
this is what I am trying to figure out
The tool mathematically places
points in the whole bounding area,
not just eligible area.
After running the tool. I am left with
lots of eligible land
Create Random Points Tool
Input 10 points. Captures 7.
Almost there… but
still a long way to go.
21. Eligible Area Static Cleanup
Eligible land less than 11,294.81 sq ft* will not
continue on to the next iteration of analysis
* the average building size for marijuana centers, marijuana stores, or marijuana
pending store/center application permits that fall within a building footprint
22. Methodology
arcpy.CreateRandomPoints_management(outpath, "point0", inputpoly, "",50,"1018 feet")
print "First random points created...."
count = int(arcpy.GetCount_management("point0").getOutput(0))
print "%s points created" % count
pointnames = []
for i in xrange(len(subsets)-1):
arcpy.Buffer_analysis("point{0}".format(i), "buff{0}".format(i), "1018 feet", dissolve_option="ALL")
print "Buffering"
arcpy.Erase_analysis("Cerase{0}".format(i), "buff{0}".format(i), "Cerase{0}".format(i+1))
print "Erase"
arcpy.FeatureClassToShapefile_conversion("Cerase{0}".format(i+1), r"R:CityDatabmoprojectsMarijuanaForAnalysis")
print "Made new shapefile for single part conversion"
arcpy.RepairGeometry_management(r"R:CityDatabmoprojectsMarijuanaForAnalysisCerase{0}.shp".format(i+1))
print "repaired"
arcpy.MultipartToSinglepart_management(r"R:CityDatabmoprojectsMarijuanaForAnalysisCerase{0}.shp".format(i+1), "SPoutput{0}".format(i+1))
print "Made single part output"
arcpy.MakeFeatureLayer_management("SPoutput{0}".format(i+1), "MFoutput{0}_lyr".format(i+1))
print "made new layer"
arcpy.SelectLayerByAttribute_management ("MFoutput{0}_lyr".format(i+1), "NEW_SELECTION", ""Shape_Area" > 11294.81")
print "selection complete"
arcpy.CopyFeatures_management("MFoutput{0}_lyr".format(i+1), "MFoutput{0}".format(i+1))
print "Made static free output"
arcpy.Dissolve_management("MFoutput{0}".format(i+1), "SPCDerase{0}".format(i+1), "DOCUMENT","", "MULTI_PART")
print "Dissolved layer"
arcpy.CreateRandomPoints_management(outpath, "point{0}".format(i+1), "SPCDerase{0}".format(i+1),"", 50, "1000 feet")
print "Make new random"
pointnames.append("point{0}".format(i+1))
icount = int(arcpy.GetCount_management("point{0}".format(i+1)).getOutput(0))
print "%s points created" % icount
if icount == 0:
break
24. Conclusion
- Random points still not perfect for “Maximum build out,” but it is
pretty close?
- Random points do reflect real world variance
- Way to improve analysis to account for market conditions and
supply/demand
Questions?
Contact information:
Grant Garstka
Grant.Garstka@denvergov.org
720.913.4907