def getNodes(proj4, nodePacks): """ Return the dataset_store.Node objects corresponding to the nodePacks (transformed into our "universal" coordinate system: longlat WGS84) """ nodes = [] transform_point = geometry_store.get_transform_point(proj4) # Check for duplicates nodePacksByCoordinates = collections.defaultdict(list) for nodePack in nodePacks: coordinates = float(nodePack['x']), float(nodePack['y']) nodePacksByCoordinates[coordinates].append(nodePack) # For each row, for coordinates, nodePacks in nodePacksByCoordinates.iteritems(): # If there are duplicates, if len(nodePacks) > 1: print 'Duplicate nodes' for nodePack in nodePacks: print '(%s) %s' % (str(coordinates), nodePack) # Add longitude, latitude = transform_point(*coordinates) nodes.append(dataset_store.Node(coordinates, (longitude, latitude), nodePacks[0])) return nodes
def generateSegments(self, nodes, computeDistance, proj4): 'Generate segment candidates connecting nodes to the existing grid' # Prepare segmentFactory = network.SegmentFactory(nodes, computeDistance, proj4) # Use more efficient CandidateManager for candidate segments candidateManager = CandidateManager(segmentFactory.getNodes(), computeDistance) net = network.Network(segmentFactory, useIndex=True) networkRelativePath = self.get(ExistingNetworks) # If we have existing networks, if networkRelativePath: # Reconstruct path networkArchivePath = os.path.join(self.state[0].getBasePath(), networkRelativePath) if not os.path.exists(networkArchivePath): raise variable_store.VariableError('Expected ZIP archive containing shapefile for existing networks') isValid, networkPath = store.unzip(networkArchivePath, 'shp') if not isValid: raise variable_store.VariableError('Could not find shapefile in ZIP archive for existing networks') # Load network networkProj4, networkGeometries = geometry_store.load(networkPath)[:2] networkCoordinatePairs = network.yieldSimplifiedCoordinatePairs(networkGeometries) # Prepare transform_point = geometry_store.get_transform_point(networkProj4, proj4) # Load existing network as a single subnet and allow overlapping segments net.addSubnet(network.Subnet([segmentFactory.getSegment(transform_point(c1[0], c1[1]), transform_point(c2[0], c2[1]), is_existing=True) for c1, c2 in networkCoordinatePairs])) # Add candidate segments that connect each node to its # projection on the existing network projectedTuples = net.projectEfficient(candidateManager.nodes) candidateManager.extendNodeTuples(projectedTuples) return candidateManager, net
def __init__(self, nodes=None, computeWeight=None, proj4=geometry_store.proj4LL): # Initialze defaults if not nodes: nodes = [] # Initialize index used to identify fake nodes self.nodeIndex = -1 # Initialize dictionaries self.nodeByCoordinates = dict((node.getCoordinates(), Node(node.id, node.getCoordinates(), node.getCommonCoordinates(), node.metric)) for node in nodes) self.segmentByCoordinates = {} # Set self.computeWeight = computeWeight if computeWeight else lambda x, y: 1 self.transform_point = geometry_store.get_transform_point(proj4)
def __init__(self, datasetPath, proj4=None): # Connect datasetPath = store.replaceFileExtension(datasetPath, "db") engine = sa.create_engine("sqlite:///" + datasetPath, echo=self.debug) metadata.create_all(engine) # Set self.session = orm.sessionmaker(bind=engine)() self.datasetPath = datasetPath # Set proj4 if proj4: self.session.execute(spatial_references_table.delete()) self.session.add(SpatialReference(proj4)) self.session.commit() self.proj4 = str(self.session.query(SpatialReference).first().proj4) self.transform_point = geometry_store.get_transform_point(self.proj4)
def __init__(self, datasetPath, proj4=None): # Connect datasetPath = store.replaceFileExtension(datasetPath, 'db') engine = sa.create_engine('sqlite:///' + datasetPath, echo=self.debug) metadata.create_all(engine) # Set self.session = orm.sessionmaker(bind=engine)() self.datasetPath = datasetPath # Set proj4 if proj4: self.session.execute(spatial_references_table.delete()) self.session.add(SpatialReference(proj4)) self.session.commit() self.proj4 = str(self.session.query(SpatialReference).first().proj4) self.transform_point = geometry_store.get_transform_point(self.proj4)
def generateSegments(self, nodes, computeDistance, proj4): 'Generate segment candidates connecting nodes to the existing grid' # Prepare segmentFactory = network.SegmentFactory(nodes, computeDistance, proj4) # Use more efficient CandidateManager for candidate segments candidateManager = CandidateManager(segmentFactory.getNodes(), computeDistance) net = network.Network(segmentFactory, useIndex=True) networkRelativePath = self.get(ExistingNetworks) # If we have existing networks, if networkRelativePath: # Reconstruct path networkArchivePath = os.path.join(self.state[0].getBasePath(), networkRelativePath) if not os.path.exists(networkArchivePath): raise variable_store.VariableError( 'Expected ZIP archive containing shapefile for existing networks' ) isValid, networkPath = store.unzip(networkArchivePath, 'shp') if not isValid: raise variable_store.VariableError( 'Could not find shapefile in ZIP archive for existing networks' ) # Load network networkProj4, networkGeometries = geometry_store.load( networkPath)[:2] networkCoordinatePairs = network.yieldSimplifiedCoordinatePairs( networkGeometries) # Prepare transform_point = geometry_store.get_transform_point( networkProj4, proj4) # Load existing network as a single subnet and allow overlapping segments net.addSubnet( network.Subnet([ segmentFactory.getSegment(transform_point(c1[0], c1[1]), transform_point(c2[0], c2[1]), is_existing=True) for c1, c2 in networkCoordinatePairs ])) # Add candidate segments that connect each node to its # projection on the existing network projectedTuples = net.projectEfficient(candidateManager.nodes) candidateManager.extendNodeTuples(projectedTuples) return candidateManager, net
def generateSegments(self, nodes, computeDistance, proj4): 'Generate segment candidates connecting nodes to the existing grid' # Prepare segments = [] segmentFactory = network.SegmentFactory(nodes, computeDistance, proj4) networkNodes = segmentFactory.getNodes() net = network.Network(segmentFactory) networkRelativePath = self.get(ExistingNetworks) # If we have existing networks, if networkRelativePath: # Reconstruct path networkArchivePath = os.path.join(self.state[0].getBasePath(), networkRelativePath) if not os.path.exists(networkArchivePath): raise variable_store.VariableError('Expected ZIP archive containing shapefile for existing networks') isValid, networkPath = store.unzip(networkArchivePath, 'shp') if not isValid: raise variable_store.VariableError('Could not find shapefile in ZIP archive for existing networks') # Load network networkProj4, networkGeometries = geometry_store.load(networkPath)[:2] networkCoordinatePairs = network.yieldSimplifiedCoordinatePairs(networkGeometries) # Prepare transform_point = geometry_store.get_transform_point(networkProj4, proj4) # Load existing network as a single subnet and allow overlapping segments net.subnets.append(network.Subnet([segmentFactory.getSegment(transform_point(c1[0], c1[1]), transform_point(c2[0], c2[1]), is_existing=True) for c1, c2 in networkCoordinatePairs])) # Add candidate segments that connect each node to its projection on the existing network segments.extend(net.project(networkNodes)) # Prepare matrix where the rows are nodes and the columns are node coordinates networkNodeMatrix = np.array([node.getCoordinates() for node in networkNodes]) # Define get_nearestNeighbors() if computeDistance == network.computeEuclideanDistance: kdTree = KDTree(networkNodeMatrix) else: earthRadiusInMeters = 6371010 kdTree = Arc_KDTree(networkNodeMatrix, radius=earthRadiusInMeters) get_nearestNeighbors = functools.partial(kdTree.query, k=self.get(MaximumNearestNeighborCount)) # For each node, for node1 in networkNodes: # Get its nearest neighbors nodeIndices = get_nearestNeighbors(node1.getCoordinates())[1] # Add candidate segments from the node to each of its nearest neighbors for node2Coordinates in networkNodeMatrix[nodeIndices]: # Let getSegment() compute segment weight in case we want to customize how we weight each segment segments.append(segmentFactory.getSegment(node1.getCoordinates(), tuple(node2Coordinates))) # Return return segments, net
def __init__(self, nodes=None, computeWeight=None, proj4=geometry_store.proj4LL): # Initialze defaults if not nodes: nodes = [] # Initialize index used to identify fake nodes self.nodeIndex = -1 # Initialize dictionaries self.nodeByCoordinates = dict( (node.getCoordinates(), Node(node.id, node.getCoordinates(), node.getCommonCoordinates(), node.metric)) for node in nodes) self.segmentByCoordinates = {} # Set self.computeWeight = computeWeight if computeWeight else lambda x, y: 1 self.transform_point = geometry_store.get_transform_point(proj4)
def show(self, id, format='html'): 'GET /scenarios/id: Show a specific item' # If the output format is not supported, if format not in ['html', 'zip', 'geojson', 'json']: return 'Unsupported output format: ' + format try: id = int(id) except ValueError: return redirect(url('scenarios')) # Load personID = h.getPersonID() c.scenario = Session.query(model.Scenario).filter(model.Scenario.id==id).filter(model.getScopeFilter(personID)).first() # If user does not have access to the scenario, if not c.scenario: c.status = model.statusFailed if format == 'html': return render('/scenarios/show.mako') elif format == 'zip': return '' elif format == 'geojson': return geojson.dumps(geojson.FeatureCollection([])) elif format == 'json': return cjson.encode({}) # If the scenario has an error, if c.scenario.status == model.statusFailed: c.traceback = c.scenario.output['traceback'] c.status = model.statusFailed if format == 'html': return render('/scenarios/show.mako') elif format == 'zip': return forward(FileApp(c.scenario.getFolder() + '.zip')) elif format == 'geojson': return geojson.dumps(geojson.FeatureCollection([])) elif format == 'json': return c.scenario.exportJSON() # If the scenario has not been processed, if c.scenario.isQueued(): c.status = model.statusPending if format == 'html': return render('/scenarios/show.mako') elif format == 'zip': return forward(FileApp(c.scenario.getFolder() + '.zip')) elif format == 'geojson': return geojson.dumps(geojson.FeatureCollection([])) elif format == 'json': return c.scenario.exportJSON() # Prepare c.status = model.statusDone c.scenarioInput = c.scenario.input c.scenarioOutput = c.scenario.output transform_point = geometry_store.get_transform_point(geometry_store.proj4LL, geometry_store.proj4SM) # If the user wants HTML, if format == 'html': # Render scenario c.metricModel = metric.getModel(c.scenarioInput['metric model name']) scenarioStatistics = c.scenarioOutput['statistics'] nodeStatistics = scenarioStatistics['node'] # Prepare map centerX, centerY = transform_point(nodeStatistics['mean longitude'], nodeStatistics['mean latitude']) box1X, box1Y = transform_point(nodeStatistics['minimum longitude'], nodeStatistics['maximum latitude']) box2X, box2Y = transform_point(nodeStatistics['maximum longitude'], nodeStatistics['minimum latitude']) # Render map datasetStore = c.scenario.getDataset() c.mapFeatures = datasetStore.exportGeoJSON(transform_point) c.mapCenter = '%s, %s' % (centerX, centerY) c.mapBox = '%s, %s, %s, %s' % (box1X, box1Y, box2X, box2Y) # Render nodes c.nodes = list(datasetStore.cycleNodes()) c.populationQuartiles = scenarioStatistics['metric']['population quartiles'] # Render scenarios c.scenarios = Session.query(model.Scenario).filter(model.getScopeFilter(personID)).filter(model.Scenario.status==model.statusDone).filter(model.Scenario.id!=c.scenario.id).order_by(model.Scenario.id.desc()).all() # Return return render('/scenarios/show.mako') elif format == 'zip': return forward(FileApp(c.scenario.getFolder() + '.zip')) elif format == 'geojson': return c.scenario.getDataset().exportGeoJSON(transform_point) elif format == 'json': return c.scenario.exportJSON(request.params.get('nodeID'))
def test(self): 'Run tests' print 'Save and load a SHP file without attributes' path = self.getPath('.shp') geometry_store.save(path, geometry_store.proj4LL, shapelyGeometries) result = geometry_store.load(path) result_proj = result[0].strip() # In some environments, proj seems to drop the ellps param which seems redundant anyway # self.assertEqual(result[0].strip(), geometry_store.proj4LL) self.assertTrue ( result_proj == geometry_store.proj4LL or result_proj == geometry_store.proj4LL.replace("+ellps=WGS84 ", "") ) self.assertEqual(len(result[1]), len(shapelyGeometries)) print 'Save and load a SHP file with attributes' path = self.getPath('.shp') geometry_store.save(path, geometry_store.proj4LL, shapelyGeometries, fieldPacks, fieldDefinitions) result = geometry_store.load(path) self.assertEqual(len(result[2]), len(fieldPacks)) for shapelyGeometry, fieldPack in itertools.izip(result[1], result[2]): print for fieldValue, (fieldName, fieldType) in itertools.izip(fieldPack, result[3]): print '%s = %s' % (fieldName, fieldValue) print shapelyGeometry print 'Save a SHP file with attributes with different targetProj4' path = self.getPath('.shp') geometry_store.save(path, geometry_store.proj4LL, shapelyGeometries, fieldPacks, fieldDefinitions, targetProj4=geometry_store.proj4SM) result = geometry_store.load(path) self.assertNotEqual(result[0].strip(), geometry_store.proj4LL) print 'Load a SHP file with attributes with different targetProj4' path = self.getPath('.shp') geometry_store.save(path, geometry_store.proj4LL, shapelyGeometries, fieldPacks, fieldDefinitions) result = geometry_store.load(path, targetProj4=geometry_store.proj4SM) self.assertNotEqual(result[0].strip(), geometry_store.proj4LL) print 'Save and load a ZIP file without attributes using save' path = self.getPath('.shp.zip') geometry_store.save(path, geometry_store.proj4LL, shapelyGeometries) result = geometry_store.load(path) result_proj = result[0].strip() self.assertTrue ( result_proj == geometry_store.proj4LL or result_proj == geometry_store.proj4LL.replace("+ellps=WGS84 ", "") ) self.assertEqual(len(result[1]), len(shapelyGeometries)) print 'Save and load a ZIP file with attributes using save' path = self.getPath('.shp.zip') geometry_store.save(path, geometry_store.proj4LL, shapelyGeometries, fieldPacks, fieldDefinitions) result = geometry_store.load(path) self.assertEqual(len(result[2]), len(fieldPacks)) print 'Test saving and loading ZIP files of point coordinates' path = self.getPath('.shp.zip') geometry_store.save_points(path, geometry_store.proj4LL, [(0, 0)], fieldPacks, fieldDefinitions) result = geometry_store.load_points(path) self.assertEqual(result[1], [(0, 0)]) print 'Test get_transform_point' transform_point0 = geometry_store.get_transform_point(geometry_store.proj4LL, geometry_store.proj4LL) transform_point1 = geometry_store.get_transform_point(geometry_store.proj4LL, geometry_store.proj4SM) self.assertNotEqual(transform_point0(0, 0), transform_point1(0, 0)) print 'Test get_transform_geometry' transform_geometry = geometry_store.get_transform_geometry(geometry_store.proj4LL, geometry_store.proj4SM) self.assertEqual(type(transform_geometry(geometry.Point(0, 0))), type(geometry.Point(0, 0))) self.assertEqual(type(transform_geometry(ogr.CreateGeometryFromWkt('POINT (0 0)'))), type(ogr.CreateGeometryFromWkt('POINT (0 0)'))) print 'Test get_coordinateTransformation' geometry_store.get_coordinateTransformation(geometry_store.proj4LL, geometry_store.proj4SM) print 'Test get_spatialReference' geometry_store.get_spatialReference(geometry_store.proj4LL) with self.assertRaises(geometry_store.GeometryError): geometry_store.get_spatialReference('') print 'Test get_geometryType' geometry_store.get_geometryType(shapelyGeometries) print 'Test save() when a fieldPack has fewer fields than definitions' with self.assertRaises(geometry_store.GeometryError): path = self.getPath('.shp') geometry_store.save(path, geometry_store.proj4LL, shapelyGeometries, [x[1:] for x in fieldPacks], fieldDefinitions) print 'Test save() when a fieldPack has more fields than definitions' with self.assertRaises(geometry_store.GeometryError): path = self.getPath('.shp') geometry_store.save(path, geometry_store.proj4LL, shapelyGeometries, [x * 2 for x in fieldPacks], fieldDefinitions) print 'Test save() when the driverName is unrecognized' with self.assertRaises(geometry_store.GeometryError): path = self.getPath('.shp') geometry_store.save(path, geometry_store.proj4LL, shapelyGeometries, driverName='') print 'Test load() when format is unrecognized' with self.assertRaises(geometry_store.GeometryError): path = self.getPath('') geometry_store.load(path)