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 
Beispiel #3
0
 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)
Beispiel #5
0
 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)
Beispiel #6
0
    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
Beispiel #7
0
 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 
Beispiel #8
0
 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)
Beispiel #9
0
 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)