__init__.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #!/usr/bin/env python
  2. # coding=utf-8
  3. from OWS import OWS
  4. import mapscript
  5. import cgi
  6. from lxml import objectify
  7. import urllib
  8. import urlparse
  9. import logging
  10. from osgeo import ogr
  11. import pyproj
  12. import os
  13. import re
  14. class WFS(OWS):
  15. service = "WFS"
  16. wfsns = "http://www.opengis.net/wfs"
  17. layerDefFile = None
  18. lyrobj = None
  19. def __init__(self,url=None,qstring=None,configFile=None):
  20. OWS.__init__(self,url,qstring,configFile)
  21. def makeMap(self,mapfilename=None):
  22. mapobj = self.getMapObj(mapfilename)
  23. # mapobjects exists, do not do any new layers
  24. if mapobj.numlayers:
  25. return mapobj
  26. self.layerDefFile = self.createLayerDefinitionFile("wfs",
  27. os.path.join( os.path.dirname(__file__), "templates",'wfs.xml'))
  28. ds = ogr.Open(self.layerDefFile)
  29. self.setMapName(mapobj)
  30. # load mapfile SYMBOLs
  31. symbolPath = os.path.join( os.path.dirname(__file__), "symbols.txt")
  32. symbolsLoaded = mapobj.setSymbolSet(symbolPath)
  33. if symbolsLoaded == mapscript.MS_SUCCESS:
  34. logging.debug("Symbols loaded from %s",symbolPath)
  35. else:
  36. logging.debug("Error loading symbols from %s",symbolPath)
  37. logging.debug(self.capabilities.contents)
  38. srss = []
  39. for name in self.capabilities.contents:
  40. mapobj.setMetaData("wms_srs",self.config.get("MapServer","srs"))
  41. mapobj.setMetaData("wfs_srs",self.config.get("MapServer","srs"))
  42. mapobj.setMetaData("wfs_connectiontimeout","90")
  43. layer = self.capabilities.contents[name]
  44. logging.debug("Creating layer %s" % name)
  45. srss = srss+filter(lambda y: not y in srss,layer.crsOptions)
  46. lyrobj = mapscript.layerObj(mapobj)
  47. #lyrobj.name = name.replace(":","_")
  48. lyrobj.name = name
  49. lyrobj.title = layer.title
  50. if layer.title:
  51. lyrobj.setMetaData("wms_title",layer.title)
  52. lyrobj.setMetaData("wfs_title",layer.title)
  53. #if layer.abstract:
  54. # lyrobj.setMetaData("ows_abstract", layer.abstract)
  55. lyrobj.setMetaData("wfs_typename", name)
  56. logging.debug("WFS version %s",self.capabilities.version)
  57. lyrobj.setMetaData("wfs_version",self.capabilities.version)
  58. lyrobj.setMetaData("gml_include_items","all")
  59. lyrobj.setMetaData("wfs_request_method","GET")
  60. lyrobj.setConnectionType(mapscript.MS_WFS,'')
  61. lyrobj.connection = self.getLayerUrl()
  62. lyrobj.data = re.sub(r".*:","",name)
  63. crs = self.__getLayerCrs(layer.crsOptions)
  64. if ds:
  65. ogrLayer = ds.GetLayerByName(name)
  66. extent = self.getLayerExtent(layer,crs)
  67. if extent:
  68. lyrobj.setMetaData("wms_extent","%s %s %s %s" % \
  69. (extent[0],extent[1],extent[2],extent[3]))
  70. lyrobj.setMetaData("wfs_extent","%s %s %s %s" % \
  71. (extent[0],extent[1],extent[2],extent[3]))
  72. lyrobj.type = self._getLayerType(ogrLayer)
  73. else:
  74. mapobj.removeLayer(mapobj.numlayers-1)
  75. logging.debug("No ogrDataSource found")
  76. continue
  77. lyrobj.setProjection(crs.getcode())
  78. #lyrobj.setProjection(layer.crsOptions[0].getcode())
  79. lyrobj.dump = mapscript.MS_TRUE
  80. lyrobj.template = "foo"
  81. cls = mapscript.classObj(lyrobj)
  82. style = mapscript.styleObj(cls)
  83. style.outlinecolor=mapscript.colorObj(134,81,0)
  84. style.color=mapscript.colorObj(238,153,0)
  85. style.size=5
  86. style.width=5
  87. if lyrobj.type == mapscript.MS_LAYER_POINT:
  88. style.symbol = 1
  89. ## overwrite already set SRSs
  90. #if len(srss) > 0:
  91. # logging.debug("Overwriting SRS option")
  92. # mapobj.setMetaData("wms_srs"," ".join(srss))
  93. self.saveMapfile(mapobj,mapfilename)
  94. return mapobj
  95. def getGeomName(self,geomname):
  96. if geomname.find("LINE") > -1:
  97. return mapscript.MS_LAYER_LINE
  98. elif geomname.find("POLYGON") > -1:
  99. return mapscript.MS_LAYER_POLYGON
  100. else:
  101. return mapscript.MS_LAYER_POINT
  102. def setMapName(self,mapobj):
  103. mapobj.name = self.config.get("MapServer","name")
  104. if self.capabilities.identification.title:
  105. mapobj.setMetaData("wms_title",self.capabilities.identification.title)
  106. mapobj.setMetaData("wfs_title",self.capabilities.identification.title)
  107. if self.capabilities.identification.abstract:
  108. mapobj.setMetaData("wms_abstract",self.capabilities.identification.abstract)
  109. mapobj.setMetaData("wfs_abstract",self.capabilities.identification.abstract)
  110. def _getLayerType(self,layer):
  111. """Returns MS layer type based on ogr.Layer.GetGeomType
  112. with ogr:
  113. wkbGeometryCollection = 7
  114. wkbGeometryCollection25D = -2147483641
  115. wkbLineString = 2
  116. wkbLineString25D = -2147483646
  117. wkbLinearRing = 101
  118. wkbMultiLineString = 5
  119. wkbMultiLineString25D = -2147483643
  120. wkbMultiPoint = 4
  121. wkbMultiPoint25D = -2147483644
  122. wkbMultiPolygon = 6
  123. wkbMultiPolygon25D = -2147483642
  124. wkbNDR = 1
  125. wkbNone = 100
  126. wkbPoint = 1
  127. wkbPoint25D = -2147483647
  128. wkbPolygon = 3
  129. wkbPolygon25D = -2147483645
  130. wkbUnknown = 0
  131. """
  132. geomType = layer.GetGeomType()
  133. if geomType == 0: # unknown
  134. # brutal force way
  135. f = layer.GetNextFeature()
  136. if f:
  137. gr = f.GetGeometryRef()
  138. geomType = gr.GetGeometryType()
  139. if geomType in [ogr.wkbPolygon,
  140. ogr.wkbMultiPolygon,
  141. ogr.wkbLinearRing]:
  142. return mapscript.MS_LAYER_POLYGON
  143. elif geomType in [ogr.wkbLineString,
  144. ogr.wkbMultiLineString]:
  145. return mapscript.MS_LAYER_LINE
  146. else:
  147. return mapscript.MS_LAYER_POINT
  148. def __getLayerCrs(self,crss):
  149. """
  150. Returns bests (non-degree) coordinate system of the layer, which is
  151. available.
  152. Ofcourse, sometimes, there is no other option, there EPSG:4326, but
  153. take somethign else, if you can
  154. """
  155. for crs in crss:
  156. if crs.getcode() == "EPSG:4326":
  157. return crs
  158. return crss[0]