Ejemplo n.º 1
0
    def snapGeometry(self, geometry, snapTolerance, mode=PreferNodes):
        """
        Snaps a QgsGeometry in the reference layer
        :param geometry: QgsGeometry
        :param snapTolerance: float
        :param mode: DsgGeometrySnapper.PreferNodes or DsgGeometrySnapper.PreferClosest
        :return:
        """
        center = QgsPointV2(geometry.boundingBox().center())

        # Get potential reference features and construct snap index
        refGeometries = []
        searchBounds = geometry.boundingBox()
        searchBounds.grow(snapTolerance)
        # filter by bounding box to get candidates
        refFeatureIds = self.index.intersects(searchBounds)

        # End here in case we don't find candidates
        if len(refFeatureIds) == 0:
            return geometry

        # speeding up the process to consider only intersecting geometries
        refFeatureRequest = QgsFeatureRequest().setFilterFids(refFeatureIds)
        for refFeature in self.referenceLayer.getFeatures(refFeatureRequest):
            refGeometry = refFeature.geometry()
            segments = self.breakQgsGeometryIntoSegments(refGeometry)
            # testing intersection
            for segment in segments:
                if segment.intersects(searchBounds):
                    refGeometries.append(segment)

        # End here in case we don't find geometries
        if len(refGeometries) == 0:
            return geometry

        # building geometry index
        refDict, index = self.buildReferenceIndex(refGeometries)
        refSnapIndex = DsgSnapIndex(center, 10*snapTolerance)
        for geom in refGeometries:
            refSnapIndex.addGeometry(geom.geometry())

        # Snap geometries
        subjGeom = geometry.geometry().clone()
        subjPointFlags = []

        # Pass 1: snap vertices of subject geometry to reference vertices
        for iPart in xrange(subjGeom.partCount()):
            subjPointFlags.append([])
            for iRing in xrange(subjGeom.ringCount(iPart)):
                subjPointFlags[iPart].append([])
                for iVert in xrange(self.polyLineSize(subjGeom, iPart, iRing)):
                    vidx = QgsVertexId(iPart, iRing, iVert, QgsVertexId.SegmentVertex)
                    p = QgsPointV2(subjGeom.vertexAt(vidx))
                    pF = QgsPoint(p.toQPointF())
                    snapPoint, snapSegment = refSnapIndex.getSnapItem(p, snapTolerance)
                    success = snapPoint or snapSegment
                    if not success:
                        subjPointFlags[iPart][iRing].append(DsgGeometrySnapper.Unsnapped )
                    else:
                        if mode == DsgGeometrySnapper.PreferNodes:
                            # Prefer snapping to point
                            if snapPoint:
                                subjGeom.moveVertex(vidx, snapPoint.getSnapPoint(p))
                                subjPointFlags[iPart][iRing].append(DsgGeometrySnapper.SnappedToRefNode)
                            elif snapSegment:
                                subjGeom.moveVertex( vidx, snapSegment.getSnapPoint(p))
                                subjPointFlags[iPart][iRing].append(DsgGeometrySnapper.SnappedToRefSegment)
                        elif mode == DsgGeometrySnapper.PreferClosest:
                            nodeSnap = None
                            segmentSnap = None
                            distanceNode = sys.float_info.max
                            distanceSegment = sys.float_info.max
                            if snapPoint:
                                nodeSnap = snapPoint.getSnapPoint(p)
                                nodeSnapF = QgsPoint(nodeSnap.toQPointF())
                                distanceNode = nodeSnapF.sqrDist(pF)
                            if snapSegment:
                                segmentSnap = snapSegment.getSnapPoint(p)
                                segmentSnapF = QgsPoint(segmentSnap.toQPointF())
                                distanceSegment = segmentSnapF.sqrDist(pF)
                            if snapPoint and (distanceNode < distanceSegment):
                                subjGeom.moveVertex( vidx, nodeSnap )
                                subjPointFlags[iPart][iRing].append(DsgGeometrySnapper.SnappedToRefNode)
                            elif snapSegment:
                                subjGeom.moveVertex(vidx, segmentSnap)
                                subjPointFlags[iPart][iRing].append(DsgGeometrySnapper.SnappedToRefSegment)

        #nothing more to do for points
        if isinstance(subjGeom, QgsPointV2):
            return QgsGeometry(subjGeom)
        
        # SnapIndex for subject feature
        subjSnapIndex = DsgSnapIndex(center, 10*snapTolerance)
        subjSnapIndex.addGeometry(subjGeom)
        
        origSubjGeom = subjGeom.clone()
        origSubjSnapIndex = DsgSnapIndex(center, 10*snapTolerance)
        origSubjSnapIndex.addGeometry(origSubjGeom)
        
        # Pass 2: add missing vertices to subject geometry
        for refGeom in refGeometries:
            for iPart in xrange(refGeom.geometry().partCount()):
                for iRing in xrange(refGeom.geometry().ringCount(iPart)):
                    for iVert in xrange(self.polyLineSize(refGeom.geometry(), iPart, iRing)):
                        point = refGeom.geometry().vertexAt(QgsVertexId(iPart, iRing, iVert, QgsVertexId.SegmentVertex))
                        # QgsPoint used to calculate squared distance
                        pointF = QgsPoint(point.toQPointF())
                        snapPoint, snapSegment = subjSnapIndex.getSnapItem(point, snapTolerance)
                        success = snapPoint or snapSegment
                        if success:
                            # Snap to segment, unless a subject point was already snapped to the reference point
                            if snapPoint and (QgsPoint(snapPoint.getSnapPoint(point).toQPointF()).sqrDist(pointF) < 1E-16):
                                continue
                            elif snapSegment:
                                # Look if there is a closer reference segment, if so, ignore this point
                                pProj = snapSegment.getSnapPoint(point)
                                pProjF = QgsPoint(pProj.toQPointF())
                                closest = refSnapIndex.getClosestSnapToPoint(point, pProj)
                                closestF = QgsPoint(closest.toQPointF())
                                if pProjF.sqrDist(pointF) > pProjF.sqrDist(closestF):
                                    continue
                                # If we are too far away from the original geometry, do nothing
                                if not origSubjSnapIndex.getSnapItem(point, snapTolerance):
                                    continue
                                idx = snapSegment.idxFrom
                                subjGeom.insertVertex(QgsVertexId(idx.vidx.part, idx.vidx.ring, idx.vidx.vertex + 1, QgsVertexId.SegmentVertex), point)
                                subjPointFlags[idx.vidx.part][idx.vidx.ring].insert(idx.vidx.vertex + 1, DsgGeometrySnapper.SnappedToRefNode )
                                subjSnapIndex = DsgSnapIndex(center, 10*snapTolerance)
                                subjSnapIndex.addGeometry(subjGeom)

        # Pass 3: remove superfluous vertices: all vertices which are snapped to a segment and not preceded or succeeded by an unsnapped vertex
        for iPart in xrange(subjGeom.partCount()):
            for iRing in xrange(subjGeom.ringCount(iPart)):
                ringIsClosed = subjGeom.vertexAt(QgsVertexId(iPart, iRing, 0, QgsVertexId.SegmentVertex)) == subjGeom.vertexAt(QgsVertexId(iPart, iRing, subjGeom.vertexCount( iPart, iRing ) - 1, QgsVertexId.SegmentVertex))
                nVerts = self.polyLineSize(subjGeom, iPart, iRing)
                iVert = 0
                while iVert < nVerts:
                    iPrev = ( iVert - 1 + nVerts ) % nVerts
                    iNext = ( iVert + 1 ) % nVerts
                    pMid = subjGeom.vertexAt(QgsVertexId( iPart, iRing, iVert, QgsVertexId.SegmentVertex))
                    pPrev = subjGeom.vertexAt(QgsVertexId( iPart, iRing, iPrev, QgsVertexId.SegmentVertex))
                    pNext = subjGeom.vertexAt(QgsVertexId( iPart, iRing, iNext, QgsVertexId.SegmentVertex))

                    pointOnSeg = self.projPointOnSegment( pMid, pPrev, pNext)
                    pointOnSegF = QgsPoint(pointOnSeg.toQPointF())
                    pMidF = QgsPoint(pMid.toQPointF())
                    dist = pointOnSegF.sqrDist(pMidF)

                    if subjPointFlags[iPart][iRing][iVert] == DsgGeometrySnapper.SnappedToRefSegment \
                     and subjPointFlags[iPart][iRing][iPrev] != DsgGeometrySnapper.Unsnapped \
                     and subjPointFlags[iPart][iRing][iNext] != DsgGeometrySnapper.Unsnapped \
                     and dist < 1E-12:
                        if (ringIsClosed and nVerts > 3 ) or ( not ringIsClosed and nVerts > 2 ):
                            subjGeom.deleteVertex(QgsVertexId(iPart, iRing, iVert, QgsVertexId.SegmentVertex))
                            del subjPointFlags[iPart][iRing][iVert]
                            iVert -= 1
                            nVerts -= 1
                        else:
                            # Don't delete vertices if this would result in a degenerate geometry
                            break
                    iVert += 1
        return QgsGeometry(subjGeom)
    def run(self):
        """Run method that performs all the real work"""
        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        GTFSDir = self.dlg.GTFSLocation.text()
        StopsFile = self.dlg.StopsFile.text()
        stopID = self.dlg.stopID.text()
        ###StopsShapefileName = self.dlg.StopsShapefileName.text()
        StopsShapefileName = "stops"
        AddToMapCanvas = False
        ##GenerateTransitServiceData = True
        SkipCalculationServiceData = False
        TrailheadData_shp = self.dlg.TrailheadData.text()
        BufferDistance = self.dlg.BufferDistance.text()
        th_id_field = self.dlg.th_id_field.text()
        th_name_field = self.dlg.th_name_field.text()
        outputGeoJSON = self.dlg.outputGeoJSON.text()
        PostGISExpr = self.dlg.tbPostGISExpr.text()		
        AddToMapCanvas = self.dlg.cbAddToMapCanvas.isChecked() # returns True if checked
        SkipCalculationServiceData = self.dlg.SkipCalculationServiceData.isChecked() # returns True if checked
        ###trailBufferShpName = self.dlg.trailBufferShpName.text()
        #in_format = []
        #in_format.append("Shapefile")
        #in_format.append("PostGIS")
        #self.dlg.comboBox.addItems(in_format)		
        trailBufferShpName = "trailBuff"
        working_dir_name = self.dlg.working_dir.text()
        #
        ##shapefile_th = self.dlg.checkBoxShapefile.isChecked() # returns True if checked
        ##postGIS_th = self.dlg.checkBoxPostGIS.isChecked()
        #
        shapefile_th = self.dlg.radioButtonShapefile.isChecked() # returns True if checked
        postGIS_th = self.dlg.radioButtonPostGIS.isChecked()
        #
        host_name = self.dlg.host_name.text()
        port = self.dlg.port.text()
        database_name = self.dlg.database_name.text()
        uname = self.dlg.uname.text()
        password = self.dlg.password.text()
        postGIS_table_name = self.dlg.postGIS_table_name.text()
        #
        InputDataSpecified = False
        if shapefile_th:
            InputDataSpecified = True
        if postGIS_th:
            InputDataSpecified = True
        #postGIS_th = True
        #shapefile_th = True		
        working_dir = os.path.join(GTFSDir, working_dir_name)
        #if working_dir doesn't exist, create it
        if not os.path.exists(working_dir):
          	os.makedirs(working_dir)   
        TATShp = os.path.join(working_dir, "TAToutput.shp")
        TATdShp = os.path.join(working_dir, "TATdoutput.shp")
        THShp = os.path.join(working_dir, "TH.shp")
        #
        DList_TrailsStops = defaultdict(list)
        #
        #####output_shp = 
        ##output_file = open(filename, 'w')
        # See if OK was pressed
        if result:
            if InputDataSpecified:
				start_time = datetime.datetime.now().replace(microsecond=0)
				stop_id = "UNK"
				stop_name = "UNK"
				stop_lat = "UNK"
				stop_lon = "UNK"
				c_stop_id = 0
				c_stop_name = 0
				c_stop_lat = 0
				c_stop_lon = 0
				counter = 0
				text_file = os.path.join(GTFSDir, StopsFile)
				#text_file = 'C:/UWGIS/Geog569/Data/Test/stops.txt' 
				##
				EPSG_code = 4326
				EPSG_code_WM = 3857
				crsSrc = QgsCoordinateReferenceSystem(4326)    # WGS 84
				crsDest = QgsCoordinateReferenceSystem(3857)  # WGS 84 / Web Mercator
				xform = QgsCoordinateTransform(crsSrc, crsDest)
				rev_xform = QgsCoordinateTransform(crsDest, crsSrc)
				##
				#StopsShapefilePath = os.path.join(GTFSDir, StopsShapefileName + ".shp")
				#StopsShapefileBufferPath = os.path.join(GTFSDir, StopsShapefileName + "BUFF.shp")
				#StopsShapefilePathWM = os.path.join(GTFSDir, StopsShapefileName + "WM.shp")
				StopsShapefilePath = os.path.join(working_dir, StopsShapefileName + ".shp")
				StopsShapefileBufferPath = os.path.join(working_dir, StopsShapefileName + "BUFF.shp")
				StopsShapefilePathWM = os.path.join(working_dir, StopsShapefileName + "WM.shp")
				##
				spatialReference = osgeo.osr.SpatialReference() #will create a spatial reference locally to tell the system what the reference will be
				spatialReference.ImportFromEPSG(int(EPSG_code)) #here we define this reference to be the EPSG code
				driver = osgeo.ogr.GetDriverByName('ESRI Shapefile') # will select the driver for our shp-file creation.
				##
				index = 0
				spatialReferenceWM = osgeo.osr.SpatialReference() #will create a spatial reference locally to tell the system what the reference will be			
				spatialReferenceWM.ImportFromEPSG(int(EPSG_code_WM)) #here we define this reference to be the EPSG code
				driver = osgeo.ogr.GetDriverByName('ESRI Shapefile') # will select the driver for our shp-file creation.
				# create layer
				#if shapefile_th_rb:
				#    print "USING Shapefiles!"
				#if postGIS_th_rb:
				#    print "USING PostGIS!"			
				##vl = QgsVectorLayer("Point", "stop_points", "memory")
				vl = QgsVectorLayer("Point?crs=EPSG:3857", "stop_points", "memory")
				##vl.spatialReference
				pr = vl.dataProvider()
				#
				# changes are only possible when editing the layer
				vl.startEditing()
				# add fields
				pr.addAttributes([QgsField("stop_id", QVariant.String),QgsField("stop_name", QVariant.Int),QgsField("stop_lat", QVariant.Double),QgsField("stop_lon", QVariant.Double)])
				index = 0
				###print "two"
				fieldnames = []
				stop_lat = 0
				stop_lon = 0
				c_stop_id = 0
				c_stop_name = 0
				c_stop_lat = 0
				c_stop_lon = 0
				with open(text_file, 'r') as f:
					first_line = f.readline()
				fl = first_line.split(",")
				counter = 0
				for f in fl:
					fieldnames.append(f)
					#for f in fl:
					#print f
					if f == "stop_id":
						c_stop_id = counter
					if f == "stop_name":
						c_stop_name = counter
					if f == "stop_lat":
						c_stop_lat = counter
						#print "stop_lat is in column ", c_stop_lat
						#print c_stop_lat
					if f == "stop_lon":
						c_stop_lon = counter
						#print "stop_lon is in column ", c_stop_lon
						##print c_stop_lon
						##print "three"
					counter = counter + 1
					#
				with open(text_file, 'r') as f:
					lines = f.readlines()
					for line in lines:
						h = '"'					
						if h in line:
							count = line.count(h)
							print "Removed quote from line" + str(count)
							while count > 0:
								#print [pos for pos, char in enumerate(line) if char == c]
								cc = [pos for pos, char in enumerate(line) if char == h]
								d = ','
								#print [pos for pos, char in enumerate(line) if char == d]
								dd = [pos for pos, char in enumerate(line) if char == d]
								startP = cc[0]
								endP = cc[1]
								for ddd in dd:
									if (ddd > startP) and (ddd < endP):
										extraCommaPos = ddd
										line1 = line[0:startP]  
										line2 = line[(startP + 1):extraCommaPos]
										line3 = line[(extraCommaPos + 1):(endP)]
										line4 = line[(endP + 1):-1]
										lineMod = line1 + line2 + line3 + line4
										#print line
										#print "Comma removed"
										#print lineMod
										line = lineMod
										count = line.count(h)
						l = str(line).split(",")
						if l[c_stop_id] != "stop_id":
							stop_id = l[c_stop_id]
						if l[c_stop_name] != "stop_name":
							stop_name = l[c_stop_name]
						if l[c_stop_lat] != "stop_lat":
							stop_lat = float(l[c_stop_lat])
						if l[c_stop_lon] != "stop_lon":
							stop_lon = float(l[c_stop_lon])
						if type(stop_lat) == float:
							if type (stop_lon) == float:
								fet = QgsFeature()
								stop_pt_WM = xform.transform(QgsPoint(stop_lon,stop_lat))
								###print "Transformed point:", stop_pt_WM
								#fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(stop_lon, stop_lat)))
								fet.setGeometry(QgsGeometry.fromPoint(stop_pt_WM))
								fet.setAttributes([stop_id, stop_name, stop_lat, stop_lon])
								pr.addFeatures([fet])
								vl.commitChanges()
				#
				# add layer to the legend
				stops_extent = vl.extent()
				xmin = stops_extent.xMinimum()			            
				ymin = stops_extent.yMinimum()
				xmax = stops_extent.xMaximum()
				ymax = stops_extent.yMaximum()
				##QgsMapLayerRegistry.instance().addMapLayer(vl)
				#
				# Add trailheads from postGIS if postGIS_th = True 			
				#
				if postGIS_th:
					uri = QgsDataSourceURI()
					# set host name, port, database name, username and password
					#uri.setConnection("localhost", "5432", "dbname", "johny", "xxx")
					uri.setConnection(host_name, port, database_name, uname, password)
					print "made PostGIS connection successfully"
					# set database schema, table name, geometry column and optionally
					# subset (WHERE clause)
					#uri.setDataSource("public", "roads", "the_geom", "cityid = 2643")
					#uri.setDataSource("public", postGIS_table_name, "geom", PostGISExpr)
					uri.setDataSource("public", postGIS_table_name, "geom", PostGISExpr)
					#
					#vlayer = QgsVectorLayer(uri.uri(), "layer name you like", "postgres")
					DB_TH_layer = QgsVectorLayer(uri.uri(), "DB_TH_layer", "postgres")
					if AddToMapCanvas:
						QgsMapLayerRegistry.instance().addMapLayer(DB_TH_layer)
					#
					stop_extent = QgsVectorLayer("Polygon?crs=EPSG:4326", "stop_extent", "memory")
					pr = stop_extent.dataProvider()
					stop_extent.startEditing()
					#
					fet = QgsFeature()
					#fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(stop_lon, stop_lat)))
					#
					stop_ex_SW = rev_xform.transform(QgsPoint(xmin, ymin))
					stop_ex_NW = rev_xform.transform(QgsPoint(xmin, ymax))
					stop_ex_NE = rev_xform.transform(QgsPoint(xmax, ymax))
					stop_ex_SE = rev_xform.transform(QgsPoint(xmax, ymin))
					print "Stops layer extent (lower):", stop_ex_SW
					print "Stops layer extent (upper):", stop_ex_NE			
					##fet.setGeometry(QgsGeometry.fromPolygon([[QgsPoint(xmin,ymin),QgsPoint(xmin,ymax), QgsPoint(xmax,ymax), QgsPoint(xmax,ymin), QgsPoint(xmin,ymin)]]))
					fet.setGeometry(QgsGeometry.fromPolygon([[stop_ex_SW, stop_ex_NW, stop_ex_NE, stop_ex_SE, stop_ex_SW]]))
					pr.addFeatures([fet])
					stop_extent.commitChanges()
					if AddToMapCanvas:
						QgsMapLayerRegistry.instance().addMapLayer(stop_extent)
					#
					print "overlay points! - using extent from stops"
					overlayAnalyzer = QgsOverlayAnalyzer()
					overlayAnalyzer.intersection(DB_TH_layer, stop_extent, THShp)
					TH_layer = QgsVectorLayer(THShp, "TH_layer", "ogr")
					if not TH_layer.isValid():
						print "TH.shp layer failed to load!"	
					########## this adds trailheads to the map canvas ########QgsMapLayerRegistry.instance().addMapLayer(TH_layer)
					iter = TH_layer.getFeatures()
					#for feature in iter:
					#    geomIn = feature.geometry()
					#    #print geom.vectorType()
					#    featgeom = geomIn.exportToWkt()
					#    print featgeom
					#    geom = QgsGeometry.fromWkt(featgeom)
					#    #print geom2 #= QgsGeometry.fromWkt(featgeom)
					#    #if geom.isMultipart:
					#    #    print "multi"
					#    feature_name = feature['name']
					#    feature_id = feature['FEAT_ID']
					#    print "geom.asPoint()"
					#    print geom.asPoint()
					#
				# add trailhead layer from shapefile if selected (assumes it is stored in WGS 84)
				#
				if shapefile_th:
					trailhead_layer = QgsVectorLayer(TrailheadData_shp, "trailhead_layer", "ogr")
					######### this adds trailsheads to map canvas############QgsMapLayerRegistry.instance().addMapLayer(trailhead_layer)
					if not trailhead_layer.isValid():
						print "trailhead layer failed to load!"
				# 
				# create trailhead layer in Web Mercator
				#
				vltWM = QgsVectorLayer("Point?crs=EPSG:3857", "trailhead_points_WM", "memory")
				prtWM = vltWM.dataProvider()
				#
				# changes - including adding fields - are only possible when editing the layer
				vltWM.startEditing()
				prtWM.addAttributes([QgsField("name", QVariant.String),QgsField("FEAT_ID", QVariant.Int)])
				#
				#  Get the features from the trailhead layer that is loaded, from shp or db
				#  and convert to a WM dataset
				#
				if shapefile_th:
					iter = trailhead_layer.getFeatures()
					print "using shape"
					for feature in iter:
						geom = feature.geometry()
						feature_name = feature['name']
						feature_id = feature['FEAT_ID']
						th_x = geom.asPoint().x()	
						th_y = geom.asPoint().y()
						print th_x, th_y
						trailhead_pt_WM = xform.transform(QgsPoint(geom.asPoint()))
						fet = QgsFeature()
						fet.setGeometry(QgsGeometry.fromPoint(trailhead_pt_WM))
						fet.setAttributes([feature_name, feature_id])
						prtWM.addFeatures([fet])
						vltWM.commitChanges()
				if postGIS_th:
					trailhead_layer = QgsVectorLayer(THShp, "trailhead_layer", "ogr")
					iter = trailhead_layer.getFeatures()
					print "using postGIS"
					for feature in iter:
						geomIn = feature.geometry()
						featgeom = geomIn.exportToWkt()
						#featgeom = featgeom.replace("MultiPoint", "POINT")					
						#featgeom = featgeom.replace("((", "(")					
						#featgeom = featgeom.replace("))", ")")					
						#featgeom = '"' + str(featgeom) + '"'
						geoString1 = featgeom.split('((')
						geoString2 = geoString1[1].split('))')
						#geoString22 = geoString2[0]	
						geoString = geoString2[0].split(' ')
						ptX = float(geoString[0])					                    
						ptY = float(geoString[1])
						#ptX = geoString[0]					
						#ptY = geoString[1]
						#geomString = '"POINT (' + str(ptX) + " " + str(ptY) + ')"'
						geomString = '"POINT (' + str(ptX) + " " + str(ptY) + ')"'
						#print geomString	
						#geom = QgsGeometry.fromWkt(geomString)
						geom = QgsGeometry.fromPoint(QgsPoint(ptX, ptY))
						#geom = QgsGeometry.fromWkt("POINT (-122.24501049999997804 47.86390650000004143)")
						###geom = feature.geometry()
						###feature_name = feature['name']
						###feature_id = feature['FEAT_ID']
						feature_name = feature[th_name_field]
						feature_id = feature[th_id_field]
						trailhead_pt_WM = xform.transform(QgsPoint(geom.asPoint()))
						fet = QgsFeature()
						fet.setGeometry(QgsGeometry.fromPoint(trailhead_pt_WM))
						fet.setAttributes([feature_name, feature_id])
						prtWM.addFeatures([fet])
						vltWM.commitChanges()
						###fet = QgsFeature()
						#####feature.asPoint()
						####print feature
						###fet.setGeometry(QgsGeometry.fromPoint(trailhead_pt_WM))
						###fet.setAttributes([feature_name, feature_id])
						###prtWM.addFeatures([fet])
						###vltWM.commitChanges()
						###fet.setGeometry(QgsGeometry.fromPoint(trailhead_pt_WM))
						###fet.setGeometry(geom)
						###fet.setAttributes([feature_name, feature_id])
						####print "geom"
						####print geom
						###trailhead_pt_WM = xform.transform(QgsPoint(geom.asPoint()))
						###prtWM.addFeatures([fet])
						###vltWM.commitChanges()
				#	
				#	Add WM trailheads to the map canvas
				#
				#print "PostGISExpr"
				#print PostGISExpr
				#if PostGISExpr == "":
				#	print "NO EXPR!"
				if AddToMapCanvas:
					QgsMapLayerRegistry.instance().addMapLayer(vltWM)
				#QgsMapLayerRegistry.instance().addMapLayer(vltWM)
				#	Buffer stops
				vltb = QgsVectorLayer("Point?crs=EPSG:3857", "trailhead_buffer_dissolved", "memory")
				#
				#QgsGeometryAnalyzer().dissolve(vlt, vltb, onlySelectedFeatures=False, uniqueIdField=-1, p=None)
				#	Buffer stops
				geometryanalyzer = QgsGeometryAnalyzer()
				geometryanalyzer.buffer(vltWM, StopsShapefileBufferPath + ".shp", int(BufferDistance), False, False, -1)
				trailheadBuffer_layer = QgsVectorLayer(StopsShapefileBufferPath + ".shp", "trailhead_buffer_layer", "ogr")
				if AddToMapCanvas:
				    QgsMapLayerRegistry.instance().addMapLayer(trailheadBuffer_layer)
				# 
				geometryanalyzer.buffer(vltWM, StopsShapefileBufferPath + "d.shp", int(BufferDistance), False, True, -1)
				#trailheadBufferd_layer = QgsVectorLayer(StopsShapefileBufferPath + "d.shp", "trailhead_buffer_d", "ogr")
				trailheadBufferd_layer = QgsVectorLayer(StopsShapefileBufferPath + "d.shp", "trailhead_buffer_d", "ogr")
				if AddToMapCanvas:
				    QgsMapLayerRegistry.instance().addMapLayer(trailheadBufferd_layer)
				# 
				# overlay - using dissolved buffer
				# 
				print "overlay points! - using dissolved buffers"
				overlayAnalyzer = QgsOverlayAnalyzer()
				#overlayAnalyzer.intersection(vl, vlt, "C:/UWGIS/Geog569/Data/Test/TAToutput.shp")
				overlayAnalyzer.intersection(vl, trailheadBufferd_layer, TATdShp)
				TATd_layer = QgsVectorLayer(TATdShp, "TransitStops_diss_layer", "ogr")
				###TATd_layer = QgsVectorLayer(TATdShp, "TrAccTrailheads_diss_layer", "ogr")
				if not TATd_layer.isValid():
					print "TATd layer failed to load!"	
				if AddToMapCanvas:
				    QgsMapLayerRegistry.instance().addMapLayer(TATd_layer)
				iter = TATd_layer.getFeatures()
				stopList = []
				for feature in iter:
					# retrieve every feature with its geometry and attributes
					feature_id = feature[stopID]
					stopList.append(feature_id)				
					#feature_id = feature['FEAT_ID']
				#for s in stopList:
				#	print s
				#
				# overlay - using the indivdual buffered points
				# this can be used to compute distance between trailhaeds and each stop in its buffer
				#				
				print "overlay points! - using dissolved buffers"
				overlayAnalyzer = QgsOverlayAnalyzer()
				#overlayAnalyzer.intersection(vl, vlt, "C:/UWGIS/Geog569/Data/Test/TAToutput.shp")
				overlayAnalyzer.intersection(vl, trailheadBuffer_layer, TATShp)
				TAT_layer = QgsVectorLayer(TATShp, "TransitStops_NonDissolved_layer", "ogr")
				#TAT_layer = QgsVectorLayer(TATShp, "TrAccTrailheads_layer", "ogr")
				if not TAT_layer.isValid():
					print "TAT layer failed to load!"	
				if AddToMapCanvas:
				    QgsMapLayerRegistry.instance().addMapLayer(TAT_layer)
				iter = TAT_layer.getFeatures()
				THstopList = []
				for feature in iter:
					# retrieve every feature with its geometry and attributes
					###trailhead_name = feature['name']
					trailhead_id = feature[th_id_field]				
					feature_id = feature[th_id_field]
					TH_Stop = str(trailhead_id) + ":" +  str(feature_id)				
					#print feature['stop_id']
					THstopList.append(TH_Stop)
					DList_TrailsStops[trailhead_id].append(feature_id)
					#feature_id = feature['FEAT_ID']
				#for s in THstopList:
				#	print s
				#for s in DList_TrailsStops:
				#	print s, DList_TrailsStops[s]
				#	#print DList_TrailsStops[s]
				print xmin, ymin, xmax, ymax
				fet = QgsFeature()
				stop_pt_WM = rev_xform.transform(QgsPoint(xmin, ymin))
				print "Stops layer extent (lower):", stop_pt_WM
				#fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(stop_lon, stop_lat)))
				stop_pt_WM = rev_xform.transform(QgsPoint(xmax, ymax))
				print "Stops layer extent (upper):", stop_pt_WM
				print self.plugin_dir
				sys.argv = [GTFSDir, stopList]
				missing_files = []
				all_files_present = True
				fn_stop_times = "stop_times.txt"
				f_stop_times = os.path.join(GTFSDir, fn_stop_times)
				if not os.path.exists(f_stop_times):
					all_files_present = False   
					missing_files.append(fn_stop_times)   
				fn_stops = "stops.txt"
				f_stops = os.path.join(GTFSDir, fn_stops)
				if not os.path.exists(f_stops):
					all_files_present = False   
					missing_files.append(fn_stops)   
				fn_trips = "trips.txt"
				f_trips = os.path.join(GTFSDir, fn_trips)
				if not os.path.exists(f_trips):
					all_files_present = False   
					missing_files.append(fn_trips)   
				fn_routes = "routes.txt"
				f_routes = os.path.join(GTFSDir, fn_routes)
				if not os.path.exists(f_routes):
					all_files_present = False   
					missing_files.append(fn_routes)   
				fn_agency = "agency.txt"
				f_agency = os.path.join(GTFSDir, fn_agency)
				if not os.path.exists(f_agency):
					all_files_present = False   
					missing_files.append(fn_agency)   
				#if working_dir doesn't exist, create it
				###if os.path.exists(f_stop_times):			
				if all_files_present:
				    if not SkipCalculationServiceData:
					    print "starting service analysis...this might take some time"   
					    SummarizeTransitService = os.path.join(self.plugin_dir, "SummarizeTransitService.py")
					    execfile(SummarizeTransitService)
				else:
					print "The GTFS appears to be incomplete.  The following files seem to be missing."   				
					#print "The GTFS appears to be incomplete.  Check that all parts are present and try again."   				
					for f in missing_files:
						print f
					##create empty dictionary
				##  BEGIN DISTANCE CODE!
				distance_dictionary = {}
				DList_TH_stops = defaultdict(list)
				### (temporarily) set ref to TAT in case
				##Enter data into Dictionary
				iter = vltWM.getFeatures()
				#iter = TAToutput.getFeatures()
				##THstopList = []
				for feature in iter:
					##identifies attributes for future use
					#print "Feature ID %d: " % feature.id()
					trailhead_id = feature[str('FEAT_ID')]
					#print trailhead_id
					geom = feature.geometry()
					th_x = geom.asPoint().x()	
					th_y = geom.asPoint().y()
					th_point = QgsPoint(th_x,th_y)
					#transit_stop_id = feature['stop_id']
					iter_stops = TAT_layer.getFeatures() ###[new layer here?]
					for stop_feature in iter_stops:
						stop_id = stop_feature[str('stop_id')]
						th_id = stop_feature[str('FEAT_ID')]
						if th_id == trailhead_id:
							stop_geom = stop_feature.geometry()
							stop_id = stop_feature['stop_id']
							DList_TH_stops[th_id].append(stop_id)
							stop_x = stop_geom.asPoint().x()	
							stop_y = stop_geom.asPoint().y()
							s_point = QgsPoint(stop_x,stop_y)
							stop_distance = 0
							a = numpy.array(th_point)
							b = numpy.array(s_point)
							##stop_distance = numpy.sqrt(numpy.sum(a-b)**2)
							stop_distance =  math.sqrt(th_point.sqrDist(s_point))
							#print th_id
							#print stop_id
							#print stop_distance
							####print math.sqrt(th_point.sqrDist(s_point))
							th_stop = str(trailhead_id) + ":" + str(stop_id)
							distance_dictionary[th_stop] = stop_distance
							#if stop_distance < BufferDistance:
							#    distance_dictionary[th_stop] = stop_distance 		
				##outputGeoJSON
				vl_outTH = QgsVectorLayer("Point?crs=EPSG:4326", "stop_points", "memory")
				pr_outTH = vl_outTH.dataProvider()
				#
				# changes are only possible when editing the layer
				vl_outTH.startEditing()
				# add fields
				##pr_outTH.addAttributes([QgsField(th_id_field, QVariant.Int),QgsField(th_name_field, QVariant.String),QgsField("number_stops_nearby", QVariant.Int),QgsField("stops_near", QVariant.String),QgsField("stops_near_dist", QVariant.String)])
				pr_outTH.addAttributes([QgsField(th_id_field, QVariant.Int),QgsField(th_name_field, QVariant.String),QgsField("number_stops_nearby", QVariant.Int),QgsField("stops_near", QVariant.String),QgsField("stops_distances", QVariant.String)])
				index = 0
				iter = trailhead_layer.getFeatures()
				for feature in iter:
					geom = feature.geometry()
					feature_id = feature[th_id_field]
					feature_name = feature[th_name_field]
					#stops_near = str(DList_TH_stops[feature_id])
					num_stops_near = 0
					stops_near_in = DList_TH_stops[feature_id]
					stops_near = []
					for t in stops_near_in:
						#print t
						if not t in stops_near:
							stops_near.append(t)					
					stops_near.sort() 
					num_stops_near = len(stops_near)
					stops_near = str(stops_near)
					stops_near = stops_near.replace("u'", "")
					stops_near = stops_near.replace("'", "")
					stops_near = stops_near.replace("[", "")
					stops_near = stops_near.replace("]", "")
					#print stops_near
					dist_list = []
					stop_list = []
					stop_dist_list = []					
					stops_near_L = DList_TH_stops[feature_id]
					stops_near_L.sort()
					for s in stops_near_L:
						#print s
						k = str(feature_id) + ":" + str(s)
						dist = distance_dictionary[k]
						dist = int(dist)
						#stop_list_data = str(s) + ', '
						#dist_list_data = str(dist) + ', '
						dist_list_data = '{stop_id: ' + str(s) + ', distance ' + str(dist) + '}'
						if not dist_list_data in dist_list:
							dist_list.append(dist_list_data)					
							stop_list.append(s)
							stop_dist_list.append(dist)
					#dist_list.sort() 
					#trailhead_pt_WM = xform.transform(QgsPoint(geom.asPoint()))
					#print "dist_list"
					#print dist_list
					#dist_list = dist_list.replace("u'", "")
					#dist_list = dist_list.replace("'", "")
					dist_list = str(dist_list)
					dist_list = dist_list.replace("[", "")
					dist_list = dist_list.replace("]", "")
					dist_list = dist_list.replace("'", "")
					fet = QgsFeature()
					fet.setGeometry(geom)
					stop_list = str(stop_list)
					stop_list = stop_list.replace("u'", "'")
					stop_dist_list = str(stop_dist_list)
					#fet.setGeometry(QgsGeometry.fromPoint(geom))
					#fet.setAttributes([feature_id, feature_name, num_stops_near, stops_near, dist_list])
					fet.setAttributes([feature_id, feature_name, num_stops_near, stop_list, stop_dist_list])
					pr_outTH.addFeatures([fet])
					vl_outTH.commitChanges()
				GeoJSONfile = os.path.join(GTFSDir, outputGeoJSON)
				writeString = ""
				QgsVectorFileWriter.writeAsVectorFormat(vl_outTH, GeoJSONfile, "utf-8", None, "GeoJSON")
				#file = open(GeoJSONfile, "w")
				##file.write(fieldnames + "\n")
				#iter = vltWM.getFeatures()
				#for feature in iter:
				#	##identifies attributes for future use
				#	#print "Feature ID %d: " % feature.id()
				#	trailhead_id = feature[str('FEAT_ID')]
				#	#trailhead_id = feature['FEAT_ID']
				#	geom = feature.geometry()
				#    th_x = geom.asPoint().x()	
				#    th_y = geom.asPoint().y()
				#    writeLine = ''
				#    writeLine = '{ "type": "Feature", "properties": { "FEAT_ID": ' + str(trailhead_id) # + '\n'
				#    #writeLine = writeLine  + ' "STOPS_NEARBY": ' + str(DList_TH_stops[trailhead_id])  ###'\n'
				#    writeLine = writeLine  + ' "STOPS_NEARBY": ' + DList_TH_stops[trailhead_id]  ###'\n'
				#    writeLine = writeLine  + '				}, "geometry": { "type": "Point", "coordinates": [ '
				#    writeLine = writeLine  + str(th_x) + ' ' + str(th_x) + ' ] } }'
				#    writeLine = writeLine  + ', \n'
				#    writeString = writeString + writeLine 
				#file.write(writeString)
				#file.close()
				end_time = datetime.datetime.now().replace(microsecond=0)
				print(end_time-start_time)
				print "done"
            else:
				print "Input trailhead data was not specified"