7

For an application I want to determine under which constituency a given coordinate falls. After looking at the various options, I decided upon shapely and fiona as the easiest way to implement this. Here is what I wrote for testing if a given coordinate is within a given constituency.

import fiona 
import shapely.geometry

fc = fiona.open("shapefile.shp")
shapefile_record = fc.next()
shape = shapely.geometry.asShape(shapefile_record['geometry'])
def is_constituency(lat,lng):
    point = shapely.geometry.Point(lat,lng)
    print shape.contains(point)

This yields false for all tests, even when I am sure the coordinate falls within said constituency.

To give an example, the first record

>>> shapefile_record['properties']
OrderedDict([(u'DIST_NAME', u'Uttarkashi'), (u'Assem_No', 2), (u'AREA', 0.003), (u'PERIMETER', 0.381), (u'INDIAASSEM', 2802.0), (u'INDIAASS', 0.0), (u'NO', 0.0), (u'ST_CODE', u'S28'), (u'AC_NAME', u'GANGOTRI'), (u'AC_TYPE', u'GEN'), (u'PC_NO', 0.0), (u'AC_NO', 2.0), (u'AC_HNAME', u'\x90\xd6\xd3\x90\xd6\xd6\xea\xa1\xd6\xdf'), (u'PARTY', u'INC'), (u'CODE_NO', u'S282'), (u'Longitude', 78.8900584624), (u'Latitude', 30.9787742252), (u'State', u'Uttaranchal'), (u'PC_NAME', u'Tehri Garhwal'), (u'PC_TYPE', u'GEN'), (u'PC_CODE', u'S2801'), (u'PC_NO_1', 1)])

Choosing the point right at the center of the constituency as described in the shapefile gives me false

>>>is_constituency(30.9787, 78.8900)
False

To make it even clearer that this is wrong, consider this:

>>> shape.contains(shapely.geometry.Point(shapefile_record['properties']['Latitude'],shapefile_record['properties']['Longitude']))
False

This means that latitude and longitude that define a polygon in its shapefile are not in the polygon?

What am I doing wrong? The whole geometry of this particular record is here:

>>> shapefile_record['geometry']
{'type': 'Polygon', 'coordinates': [[(78.38236181915738, 31.26909614048731), (78.37916181915745, 31.268796140487385), (78.3822618191574, 31.267896140487327), (78.3863618191574, 31.25889614048731), (78.38236181915738, 31.26909614048731), (78.39066181915734, 31.27209614048735), (78.39166181915749, 31.26569614048737), (78.39476181915734, 31.261196140487364), (78.40206181915738, 31.253896140487317), (78.40136181915733, 31.247396140487414), (78.40616181915749, 31.242696140487347), (78.40616181915749, 31.23999614048722), (78.42386181915737, 31.242196140487348), (78.42906181915743, 31.251396140487262), (78.43636181915747, 31.24869614048731), (78.43946181915743, 31.241396140487275), (78.45286181915736, 31.236896140487264), (78.46626181915747, 31.219596140487393), (78.47446181915734, 31.213196140487415), (78.47546181915749, 31.203196140487254), (78.47896181915735, 31.201496140487286), (78.47846181915736, 31.194996140487323), (78.47896181915735, 31.19249614048727), (78.48206181915737, 31.184496140487397), (78.47876181915751, 31.19379614048734), (78.4857618191574, 31.196796140487265), (78.52196181915735, 31.195196140487383), (78.54586181915738, 31.198096140487337), (78.55736181915728, 31.210896140487364), (78.5636618191574, 31.219196140487334), (78.5688618191574, 31.22109614048736), (78.57406181915741, 31.225696140487283), (78.58656181915745, 31.227596140487265), (78.59066181915745, 31.226696140487267), (78.59438800139878, 31.2276993433984), (78.59466544240831, 31.215214497963416), (78.59476181915738, 31.21519614048731), (78.59136181915744, 31.17679614048729), (78.59196181915752, 31.172796140487268), (78.59266181915734, 31.164396140487323), (78.59336181915734, 31.16029614048739), (78.59396181915747, 31.155696140487294), (78.59476181915738, 31.15239614048727), (78.59456181915738, 31.14619614048729), (78.59436181915748, 31.141196140487295), (78.5928618191574, 31.133996140487348), (78.5905618191573, 31.12569614048732), (78.58506181915737, 31.11289614048735), (78.5836618191575, 31.10639614048739), (78.58076181915737, 31.096596140487296), (78.58046181915745, 31.09129614048732), (78.57956181915739, 31.08559614048733), (78.57696181915736, 31.076796140487325), (78.57396181915749, 31.071496140487405), (78.56966181915732, 31.06689614048731), (78.56486181915739, 31.060396140487345), (78.56036181915738, 31.055896140487338), (78.55746181915742, 31.052096140487386), (78.55496181915748, 31.046596140487395), (78.5543618191574, 31.041796140487406), (78.5548618191574, 31.038396140487293), (78.55676181915737, 31.034696140487252), (78.55856181915749, 31.0320961404874), (78.56126181915738, 31.02909614048736), (78.56596181915745, 31.02629614048732), (78.5732618191575, 31.023096140487386), (78.57816181915734, 31.02039614048727), (78.58316181915734, 31.016896140487408), (78.58716181915736, 31.012596140487236), (78.58916181915748, 31.00639614048726), (78.58886181915733, 31.001996140487396), (78.58746181915751, 30.995996140487247), (78.58346181915749, 30.986896140487318), (78.57896181915748, 30.980196140487354), (78.57056181915738, 30.972696140487248), (78.56596181915745, 30.96759614048733), (78.56176181915737, 30.968296140487386), (78.55476181915748, 30.971496140487265), (78.5496618191574, 30.974296140487304), (78.54546181915731, 30.976396140487346), (78.53686181915737, 30.98029614048727), (78.52476181915739, 30.983996140487363), (78.51606181915747, 30.986996140487406), (78.50816181915735, 30.990596140487355), (78.50236181915744, 30.992896140487236), (78.49326181915751, 30.995196140487277), (78.48246181915738, 30.999296140487274), (78.47446181915734, 31.0025961404873), (78.46366181915744, 31.005896140487263), (78.45626181915748, 31.007296140487316), (78.44656181915747, 31.007196140487395), (78.4316618191574, 31.004596140487365), (78.41926181915744, 31.001396140487266), (78.4112618191574, 30.99869614048737), (78.38606181915742, 30.98579614048726), (78.37846181915745, 30.981396140487337), (78.37416181915745, 30.9783961404873), (78.36956181915735, 30.973696140487395), (78.36226181915748, 30.9683961404873), (78.35336181915739, 30.962196140487322), (78.34116181915743, 30.953296140487396), (78.33196181915741, 30.947096140487254), (78.32336181915747, 30.94129614048734), (78.31436181915745, 30.93129614048735), (78.30736181915734, 30.92489614048736), (78.30266181915749, 30.92099614048726), (78.30016181915744, 30.919296140487294), (78.30116181915736, 30.91489614048737), (78.3021618191575, 30.90809614048732), (78.30356181915738, 30.901896140487345), (78.30516181915738, 30.89799614048741), (78.30666181915751, 30.89399614048739), (78.30926181915737, 30.89179614048726), (78.3134618191574, 30.888796140487333), (78.3177618191574, 30.887196140487337), (78.3229618191574, 30.88539614048722), (78.33026181915744, 30.884896140487236), (78.33486181915737, 30.88459614048731), (78.33986181915736, 30.884696140487396), (78.34626181915735, 30.88499614048738), (78.35076181915736, 30.88479614048731), (78.35426181915744, 30.88459614048731), (78.35746181915732, 30.881596140487257), (78.35656181915749, 30.87819614048732), (78.3564618191574, 30.872696140487342), (78.35476181915743, 30.86789614048735), (78.35346181915747, 30.864896140487307), (78.34546181915744, 30.864996140487396), (78.33756181915749, 30.864596140487325), (78.33196181915741, 30.86419614048731), (78.32406181915746, 30.863896140487327), (78.31806181915732, 30.86529614048738), (78.3147618191573, 30.865196140487235), (78.30956181915747, 30.864696140487297), (78.3039618191574, 30.86399614048725), (78.30076181915751, 30.863496140487253), (78.2982618191574, 30.861796140487286), (78.29416181915747, 30.859296140487405), (78.29186181915742, 30.85379614048725), (78.28946181915745, 30.848196140487346), (78.2874618191575, 30.84429614048725), (78.28206181915743, 30.842096140487282), (78.27806181915741, 30.838696140487343), (78.27956181915738, 30.83389614048741), (78.28066181915744, 30.829396140487404), (78.28196181915735, 30.825696140487317), (78.28436181915731, 30.819196140487414), (78.28906181915738, 30.80999614048733), (78.28686181915742, 30.80739614048736), (78.27936181915737, 30.803196140487277), (78.27506181915737, 30.800396140487237), (78.2684618191575, 30.797696140487343), (78.26506181915738, 30.795996140487375), (78.26056181915737, 30.79379614048742), (78.25076181915745, 30.78969614048725), (78.24396181915739, 30.786496140487372), (78.23526181915747, 30.783296140487273), (78.23076181915746, 30.78189614048722), (78.22346181915742, 30.78129614048732), (78.21266181915735, 30.78209614048729), (78.20646181915737, 30.77979614048741), (78.2034618191575, 30.7765961404873), (78.19866181915734, 30.771996140487378), (78.1982618191575, 30.76849614048735), (78.19496181915747, 30.7657961404874), (78.1941618191575, 30.76849614048735), (78.1882618191575, 30.768696140487354), (78.18196181915744, 30.76849614048735), (78.17716181915745, 30.767596140487285), (78.1705618191574, 30.766796140487372), (78.1655618191574, 30.765196140487326), (78.1571618191573, 30.761596140487317), (78.15196181915746, 30.75959614048725), (78.14906181915751, 30.762696140487215), (78.1449618191574, 30.76359614048727), (78.14086181915746, 30.763296140487288), (78.13816181915752, 30.766696140487227), (78.13466181915749, 30.768696140487354), (78.13146181915738, 30.76999614048725), (78.12666181915739, 30.772496140487362), (78.12206181915747, 30.775196140487314), (78.11796181915736, 30.77759614048728), (78.11526181915741, 30.778296140487267), (78.1120618191573, 30.77909614048741), (78.11366181915736, 30.775796140487387), (78.11616181915747, 30.77089614048731), (78.11956181915741, 30.766796140487372), (78.1216618191574, 30.764196140487346), (78.12206181915747, 30.760596140487394), (78.1222618191573, 30.757596140487294), (78.11986181915734, 30.753796140487342), (78.10956181915742, 30.744096140487272), (78.09856181915728, 30.73499614048734), (78.0910618191574, 30.72659614048741), (78.0867618191574, 30.720396140487257), (78.08396181915737, 30.714796140487355), (78.0828618191573, 30.711096140487314), (78.08126181915748, 30.713696140487283), (78.07856181915736, 30.716596140487248), (78.07536181915742, 30.719296140487362), (78.07366181915745, 30.7217961404873), (78.07096181915733, 30.725196140487412), (78.06776181915745, 30.729996140487348), (78.06386181915735, 30.733296140487372), (78.06136181915741, 30.735496140487328), (78.05796181915747, 30.738896140487274), (78.05526181915735, 30.742196140487298), (78.05156181915748, 30.745096140487252), (78.04776181915747, 30.749396140487423), (78.0451618191575, 30.751496140487234), (78.04296181915737, 30.75349614048736), (78.04036181915751, 30.755596140487402), (78.03636181915749, 30.75919614048735), (78.03486181915736, 30.763696140487358), (78.03276181915732, 30.766496140487398), (78.03016181915734, 30.77049614048741), (78.02776181915738, 30.7733961404872), (78.02516181915735, 30.77759614048728), (78.02266181915746, 30.78209614048729), (78.0192618191573, 30.7867961404873), (78.01706181915739, 30.790296140487335), (78.01516181915736, 30.792396140487376), (78.01106181915742, 30.79529614048733), (78.0072618191574, 30.796896140487373), (78.0034618191574, 30.797596140487197), (77.99986181915745, 30.79909614048734), (77.99666181915734, 30.80249614048728), (77.99416181915745, 30.806196140487376), (77.99146181915751, 30.812796140487194), (77.99096181915752, 30.816196140487303), (77.98916181915746, 30.82399614048734), (77.98846181915746, 30.8274961404872), (77.98816181915748, 30.831296140487385), (77.98656181915743, 30.83749614048736), (77.98476181915737, 30.842296140487353), (77.98466181915745, 30.845896140487305), (77.98466181915745, 30.852896140487413), (77.98386181915737, 30.859296140487405), (77.98486181915729, 30.862696140487344), (77.9843618191573, 30.869096140487333), (77.98516181915744, 30.872996140487267), (77.98586181915744, 30.876396140487206), (77.98866181915747, 30.879696140487404), (77.99156181915743, 30.88219614048734), (77.99446181915738, 30.883896140487312), (78.00446181915737, 30.885996140487293), (78.00946181915737, 30.886796140487263), (78.01196181915748, 30.888896140487304), (78.0159618191575, 30.892996140487416), (78.0159618191575, 30.896796140487254), (78.01586181915735, 30.89899614048739), (78.01346181915738, 30.90429614048731), (78.01216181915748, 30.908696140487397), (78.01176181915741, 30.912696140487416), (78.00856181915731, 30.91729614048734), (78.00436181915745, 30.921996140487348), (78.00016181915743, 30.924996140487284), (77.99526181915735, 30.928796140487236), (77.99296181915747, 30.931096140487348), (77.99036181915744, 30.932896140487404), (77.9867618191575, 30.936096140487283), (77.98506181915735, 30.93869614048731), (77.98446181915745, 30.942096140487248), (77.98466181915745, 30.94429614048739), (77.98326181915746, 30.947596140487413), (77.97936181915736, 30.949896140487283), (77.97596181915742, 30.950196140487208), (77.97236181915741, 30.950696140487192), (77.96776181915749, 30.950596140487278), (77.96436181915738, 30.950296140487353), (77.96046181915744, 30.95039614048728), (77.95586181915735, 30.950196140487208), (77.95066181915752, 30.94969614048728), (77.94546181915729, 30.949396140487295), (77.94016181915737, 30.948096140487397), (77.93406181915748, 30.94589614048727), (77.92546181915736, 30.941996140487333), (77.92026181915736, 30.938396140487384), (77.91686181915742, 30.93569614048727), (77.91336181915733, 30.93229614048733), (77.91036181915746, 30.929896140487305), (77.90596181915737, 30.927796140487324), (77.90036181915747, 30.926196140487267), (77.89326181915749, 30.924996140487284), (77.8890618191574, 30.925396140487297), (77.88546181915746, 30.926896140487266), (77.88296181915734, 30.9285961404874), (77.87966181915732, 30.931596140487276), (77.87726181915735, 30.93339614048739), (77.87466181915738, 30.93549614048721), (77.8723618191575, 30.938896140487323), (77.8680618191575, 30.94229614048726), (77.86506181915746, 30.945196140487273), (77.86316181915743, 30.94849614048724), (77.85956181915748, 30.95529614048735), (77.85616181915736, 30.963096140487323), (77.85386181915749, 30.9677961404874), (77.85236181915735, 30.971696140487325), (77.85136181915738, 30.977696140487243), (77.85026181915748, 30.98859614048729), (77.84996181915739, 30.994996140487277), (77.84926181915733, 31.001196140487256), (77.84846181915742, 31.007996140487304), (77.84626181915746, 31.017496140487317), (77.84636181915738, 31.02079614048734), (77.84596181915737, 31.025396140487263), (77.84626181915746, 31.02989614048727), (77.84626181915746, 31.03359614048737), (77.84556181915747, 31.04029614048733), (77.84476181915733, 31.045796140487255), (77.84596181915737, 31.0517961404874), (77.84546938751679, 31.055538620956156), (77.84517669242553, 31.055412360328493), (77.84517526714767, 31.055467946167376), (77.84503312325421, 31.061011558012634), (77.85036181915738, 31.061096140487333), (77.85656181915738, 31.064796140487278), (77.86386181915739, 31.079496140487276), (77.86486181915738, 31.08949614048727), (77.86586181915737, 31.094896140487307), (77.87106181915738, 31.100496140487337), (77.88666181915741, 31.107896140487316), (77.89296181915745, 31.10979614048731), (77.89296181915745, 31.117096140487327), (77.89396181915743, 31.122496140487275), (77.9032618191574, 31.133596140487274), (77.90116181915737, 31.139896140487284), (77.90636181915737, 31.142696140487285), (77.91476181915738, 31.143696140487275), (77.92206181915738, 31.140996140487285), (77.92836181915737, 31.141996140487276), (77.94716181915737, 31.153096140487285), (77.95136181915737, 31.153196140487275), (77.95336181915737, 31.156796140487273), (77.95856181915737, 31.162396140487285), (77.96796181915737, 31.164296140487277), (77.98266181915737, 31.15079614048728), (77.99936181915737, 31.15369614048728), (78.00566181915737, 31.152796140487283), (78.01926181915736, 31.143796140487275), (78.02756181915737, 31.141196140487278), (78.03066181915744, 31.1453961404873), (78.03266181915738, 31.137896140487282), (78.03166181915748, 31.14599614048723), (78.03166181915748, 31.151296140487382), (78.03066181915744, 31.1453961404873), (78.02866181915738, 31.152096140487295), (78.02856181915746, 31.15849614048733), (78.04006181915736, 31.166796140487293), (78.04316181915738, 31.17229614048728), (78.05156181915748, 31.174196140487254), (78.0661618191574, 31.17979614048733), (78.08706181915738, 31.17999614048739), (78.09226181915739, 31.178196140487334), (78.09856181915728, 31.178296140487422), (78.10586181915733, 31.181096140487284), (78.11416181915752, 31.18849614048742), (78.12046181915741, 31.191296140487285), (78.12256181915745, 31.1939961404874), (78.12566181915747, 31.194996140487323), (78.13196181915737, 31.20229614048736), (78.14656181915745, 31.20519614048737), (78.14866181915744, 31.21159614048736), (78.15756181915737, 31.2143961404874), (78.16006181915748, 31.21989614048738), (78.16736181915735, 31.21909614048741), (78.17266181915744, 31.2208961404873), (78.17786181915744, 31.220096140487392), (78.18206181915735, 31.220996140487273), (78.18726181915736, 31.219296140487305), (78.19876181915743, 31.212096140487347), (78.20396181915748, 31.21119614048729), (78.21126181915736, 31.214896140487387), (78.21436181915749, 31.223096140487257), (78.2185618191574, 31.226796140487355), (78.2237618191574, 31.227796140487325), (78.2289618191574, 31.228796140487248), (78.24256181915734, 31.2251961404873), (78.24886181915741, 31.229796140487394), (78.24886181915741, 31.234396140487327), (78.25406181915747, 31.23349614048732), (78.25926181915747, 31.237196140487356), (78.26026181915745, 31.24089614048728), (78.26346181915733, 31.243696140487316), (78.26556181915737, 31.24729614048727), (78.27286181915741, 31.255596140487285), (78.28016181915746, 31.262096140487422), (78.28846181915748, 31.25759614048741), (78.29786181915733, 31.25489614048729), (78.30416181915746, 31.25679614048727), (78.30626181915744, 31.264996140487373), (78.30626181915744, 31.275096140487285), (78.30946181915738, 31.277896140487314), (78.31566181915736, 31.276996140487256), (78.32606181915742, 31.276196140487347), (78.33656181915751, 31.278996140487383), (78.34486181915736, 31.277296140487415), (78.3573618191574, 31.28099614048728), (78.36576181915734, 31.28199614048725), (78.37826181915739, 31.279396140487226), (78.38236181915738, 31.26909614048731)]]}

The data I am using can be found here.

11

If we examine your polygon:

polygon = shapefile_record['geometry']
print polygon.bounds
(77.84476181915733, 30.711096140487314, 78.59476181915738, 31.28199614048725)

From Shapely manual, object.bounds:

Returns a (minx, miny, maxx, maxy) tuple (float values) that bounds the object.

Here minx = 77.84476181915733, miny = 30.711096140487314

= here, min longitude = 77.844... and min latitude = 30.711...

Setting your point as Point(30.9787, 78.8900) or Point(latitude, longitude), you reverse the coordinates:

your_point = Point(30.9787, 78.8900) # = Point(y, x)
xy_point = Point(78.8900,30.9787) # = Point(x,y)
polygon.contains(xy_point)
False

Which is correct:

enter image description here

So, the script with your example:

from shapely.geometry import Point, shape
point = Point(78.8900,30.9787)
fc = fiona.open("AC_All_Final.shp")
print fc.schema
{'geometry': 'Polygon', 'properties': OrderedDict([(u'DIST_NAME', 'str:254'), (u'Assem_No', 'int:4'), (u'AREA', 'float:18.3'), (u'PERIMETER', 'float:18.3'), (u'INDIAASSEM', 'float:11'), (u'INDIAASS', 'float:11'), (u'NO', 'float:11'), (u'ST_CODE', 'str:254'), (u'AC_NAME', 'str:254'), (u'AC_TYPE', 'str:254'), (u'PC_NO', 'float:11'), (u'AC_NO', 'float:19.11'), (u'AC_HNAME', 'str:254'), (u'PARTY', 'str:254'), (u'CODE_NO', 'str:254'), (u'Longitude', 'float:19.17'), (u'Latitude', 'float:19.17'), (u'State', 'str:50'), (u'PC_NAME', 'str:25'), (u'PC_TYPE', 'str:3'), (u'PC_CODE', 'str:10'), (u'PC_NO_1', 'int:4')])}
from feature in fc:
    if shape(feature['geometry']).contains(point):
          print feature['properties']['DIST_NAME'], feature['properties']['Longitude'], feature['properties']['Latitude']

Uttarkashi 78.8900584624 30.9787742252

Result:

enter image description here

  • 2
    What Gene said :) Your shapefile's coordinates are in lng, lat order so you've been comparing geometries from two different coordinate systems. That won't give you the right result ever except by accident. This isn't Shapely's fault at all and a retitling of this post is in order, IMO. – sgillies Jan 24 '14 at 15:56
  • I feel like an idiot now. Which library did you use to plot the first map? – kuch nahi Jan 24 '14 at 17:38
  • matplotlib for the two figures – gene Jan 24 '14 at 18:07
  • Sorry :( BTW, this is pretty much the reason why GeoJSON uses longitude, latitude order in its coordinates: when you get a geographic Shapefile you'll almost always find longitude as the X and latitude as the Y. – sgillies Jan 24 '14 at 20:38
  • 1
    shouldn't it be for feature in fc: if shape(feature['geometry']).contains(point): – SIslam Oct 29 '15 at 18:20

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.