示例#1
0
def validate_polygon(obj):
    """
    Make sure an input can be returned as a valid polygon.

    Parameters
    -------------
    obj : shapely.geometry.Polygon, str (wkb), or (n, 2) float
      Object which might be a polygon

    Returns
    ------------
    polygon : shapely.geometry.Polygon
      Valid polygon object

    Raises
    -------------
    ValueError
      If a valid finite- area polygon isn't available
    """
    if isinstance(obj, Polygon):
        polygon = obj
    elif util.is_shape(obj, (-1, 2)):
        polygon = Polygon(obj)
    elif util.is_string(obj):
        polygon = load_wkb(obj)
    else:
        raise ValueError('Input not a polygon!')

    if (not polygon.is_valid or
            polygon.area < tol.zero):
        raise ValueError('Polygon is zero- area or invalid!')
    return polygon
示例#2
0
def validate_polygon(obj):
    """
    Make sure an input can be returned as a valid polygon.

    Parameters
    -------------
    obj : shapely.geometry.Polygon, str (wkb), or (n, 2) float
      Object which might be a polygon

    Returns
    ------------
    polygon : shapely.geometry.Polygon
      Valid polygon object

    Raises
    -------------
    ValueError
      If a valid finite- area polygon isn't available
    """
    if isinstance(obj, Polygon):
        polygon = obj
    elif util.is_shape(obj, (-1, 2)):
        polygon = Polygon(obj)
    elif util.is_string(obj):
        polygon = load_wkb(obj)
    else:
        raise ValueError('Input not a polygon!')

    if (not polygon.is_valid or polygon.area < tol.zero):
        raise ValueError('Polygon is zero- area or invalid!')
    return polygon
示例#3
0
    def test_polygon(self):
        coords = ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0))

        # Construct a polygon, exterior ring only
        polygon = Polygon(coords)
        self.assertEqual(len(polygon.exterior.coords), 5)

        # Ring Access
        self.assertIsInstance(polygon.exterior, LinearRing)
        ring = polygon.exterior
        self.assertEqual(len(ring.coords), 5)
        self.assertEqual(ring.coords[0], ring.coords[4])
        self.assertEqual(ring.coords[0], (0., 0.))
        self.assertTrue(ring.is_ring)
        self.assertEqual(len(polygon.interiors), 0)

        # Create a new polygon from WKB
        data = polygon.wkb
        polygon = None
        ring = None
        polygon = load_wkb(data)
        ring = polygon.exterior
        self.assertEqual(len(ring.coords), 5)
        self.assertEqual(ring.coords[0], ring.coords[4])
        self.assertEqual(ring.coords[0], (0., 0.))
        self.assertTrue(ring.is_ring)
        polygon = None

        # Interior rings (holes)
        polygon = Polygon(coords, [((0.25, 0.25), (0.25, 0.5),
                                    (0.5, 0.5), (0.5, 0.25))])
        self.assertEqual(len(polygon.exterior.coords), 5)
        self.assertEqual(len(polygon.interiors[0].coords), 5)
        with self.assertRaises(IndexError):  # index out of range
            polygon.interiors[1]

        # Test from another Polygon
        copy = Polygon(polygon)
        self.assertEqual(len(polygon.exterior.coords), 5)
        self.assertEqual(len(polygon.interiors[0].coords), 5)
        with self.assertRaises(IndexError):  # index out of range
            polygon.interiors[1]

        # Coordinate getters and setters raise exceptions
        self.assertRaises(NotImplementedError, polygon._get_coords)
        with self.assertRaises(NotImplementedError):
            polygon.coords

        # Geo interface
        self.assertEqual(
            polygon.__geo_interface__,
            {'type': 'Polygon',
             'coordinates': (((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0),
                             (0.0, 0.0)), ((0.25, 0.25), (0.25, 0.5),
                             (0.5, 0.5), (0.5, 0.25), (0.25, 0.25)))})

        # Error handling
        with self.assertRaises(ValueError):
            # A LinearRing must have at least 3 coordinate tuples
            Polygon([[1, 2], [2, 3]])
 def _load_geometry(self, wkb_or_wkt):
     try:
         return load_wkb(wkb_or_wkt)
     except:
         try:
             return load_wkt(wkb_or_wkt)
         except:
             return None
示例#5
0
    def _load_geometry(self, geometry_spec):
        if isinstance(geometry_spec, BaseGeometry):
            return geometry_spec

        try:
            return load_wkb(geometry_spec)
        except:
            try:
                return load_wkt(geometry_spec)
            except:
                return None
    def _load_geometry(self, geometry_spec):
        if isinstance(geometry_spec, BaseGeometry):
            return geometry_spec

        try:
            return load_wkb(geometry_spec)
        except:
            try:
                return load_wkt(geometry_spec)
            except:
                return None
示例#7
0
def validate_polygon(obj):
    if util.is_instance_named(obj, 'Polygon'):
        polygon = obj
    elif util.is_shape(obj, (-1, 2)):
        polygon = Polygon(obj)
    elif util.is_string(obj):
        polygon = load_wkb(obj)
    else:
        raise ValueError('Input not a polygon!')

    if (not polygon.is_valid or polygon.area < tol.zero):
        raise ValueError('Polygon is zero- area or invalid!')
    return polygon
示例#8
0
文件: creation.py 项目: embr/trimesh
def validate_polygon(obj):
    if util.is_instance_named(obj, 'Polygon'):
        polygon = obj
    elif util.is_shape(obj, (-1,2)):
        polygon = Polygon(obj)
    elif util.is_string(obj):
        polygon = load_wkb(obj)
    else:
        raise ValueError('Input not a polygon!')
        
    if (not polygon.is_valid or
        polygon.area < tol.zero):
        raise ValueError('Polygon is zero- area or invalid!')
    return polygon
示例#9
0
    def test_polygon(self):
        coords = ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0))

        # Construct a polygon, exterior ring only
        polygon = Polygon(coords)
        assert len(polygon.exterior.coords) == 5

        # Ring Access
        assert isinstance(polygon.exterior, LinearRing)
        ring = polygon.exterior
        assert len(ring.coords) == 5
        assert ring.coords[0] == ring.coords[4]
        assert ring.coords[0] == (0.0, 0.0)
        assert ring.is_ring is True
        assert len(polygon.interiors) == 0

        # Create a new polygon from WKB
        data = polygon.wkb
        polygon = None
        ring = None
        polygon = load_wkb(data)
        ring = polygon.exterior
        assert len(ring.coords) == 5
        assert ring.coords[0] == ring.coords[4]
        assert ring.coords[0] == (0.0, 0.0)
        assert ring.is_ring is True
        polygon = None

        # Interior rings (holes)
        polygon = Polygon(coords, [((0.25, 0.25), (0.25, 0.5), (0.5, 0.5),
                                    (0.5, 0.25))])
        assert len(polygon.exterior.coords) == 5
        assert len(polygon.interiors[0].coords) == 5
        with pytest.raises(IndexError):  # index out of range
            polygon.interiors[1]

        # Coordinate getter raises exceptions
        with pytest.raises(NotImplementedError):
            polygon.coords

        # Geo interface
        assert polygon.__geo_interface__ == {
            "type":
            "Polygon",
            "coordinates": (
                ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0)),
                ((0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25), (0.25,
                                                                      0.25)),
            ),
        }
示例#10
0
    def _load_geometry(self, geometry_spec):
        if isinstance(geometry_spec, BaseGeometry):
            return geometry_spec

        if isinstance(geometry_spec, dict):
            return SimpleShape(geometry_spec['coordinates'],
                               geometry_spec["type"])

        try:
            return load_wkb(geometry_spec)
        except Exception:
            try:
                return load_wkt(geometry_spec)
            except Exception:
                return None
示例#11
0
    def _load_geometry(self, geometry_spec):
        if isinstance(geometry_spec, BaseGeometry):
            return geometry_spec

        if isinstance(geometry_spec, dict):
            return SimpleShape(geometry_spec['coordinates'],
                               geometry_spec["type"])

        try:
            return load_wkb(geometry_spec)
        except Exception:
            try:
                return load_wkt(geometry_spec)
            except Exception:
                return None
示例#12
0
    def _loadGeometry(self, geometrySpec):
        """
        A private method to convert a (E)WKB or (E)WKT to a Shapely geometry.
        """
        if type(geometrySpec) is str and geometrySpec.startswith('POLYGON Z'):
            try:
                geometry = load_wkt(geometrySpec)
            except Exception:
                geometry = None
        else:
            try:
                geometry = load_wkb(geometrySpec)
            except Exception:
                geometry = None

        if geometry is None:
            raise ValueError('Failed to convert WKT or WKB to a Shapely geometry')

        return geometry
示例#13
0
    def _loadGeometry(self, geometrySpec):
        """
        A private method to convert a (E)WKB or (E)WKT to a Shapely geometry.
        """
        if type(geometrySpec) is str and geometrySpec.startswith('POLYGON Z'):
            try:
                geometry = load_wkt(geometrySpec)
            except Exception:
                geometry = None
        else:
            try:
                geometry = load_wkb(geometrySpec)
            except Exception:
                geometry = None

        if geometry is None:
            raise ValueError('Failed to convert WKT or WKB to a Shapely geometry')

        return geometry
示例#14
0
    def test_polygon(self):

        # Initialization
        # Linear rings won't usually be created by users, but by polygons
        coords = ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0))
        ring = LinearRing(coords)
        self.assertEqual(len(ring.coords), 5)
        self.assertEqual(ring.coords[0], ring.coords[4])
        self.assertEqual(ring.coords[0], ring.coords[-1])
        self.assertTrue(ring.is_ring)

        # Coordinate modification
        ring.coords = ((0.0, 0.0), (0.0, 2.0), (2.0, 2.0), (2.0, 0.0))
        self.assertEqual(
            ring.__geo_interface__, {
                'type':
                'LinearRing',
                'coordinates':
                ((0.0, 0.0), (0.0, 2.0), (2.0, 2.0), (2.0, 0.0), (0.0, 0.0))
            })

        # Test ring adapter
        coords = [[0.0, 0.0], [0.0, 1.0], [1.0, 1.0], [1.0, 0.0]]
        ra = asLinearRing(coords)
        self.assertTrue(ra.wkt.upper().startswith('LINEARRING'))
        self.assertEqual(dump_coords(ra), [(0.0, 0.0), (0.0, 1.0), (1.0, 1.0),
                                           (1.0, 0.0), (0.0, 0.0)])
        coords[3] = [2.0, -1.0]
        self.assertEqual(dump_coords(ra), [(0.0, 0.0), (0.0, 1.0), (1.0, 1.0),
                                           (2.0, -1.0), (0.0, 0.0)])

        # Construct a polygon, exterior ring only
        polygon = Polygon(coords)
        self.assertEqual(len(polygon.exterior.coords), 5)

        # Ring Access
        self.assertIsInstance(polygon.exterior, LinearRing)
        ring = polygon.exterior
        self.assertEqual(len(ring.coords), 5)
        self.assertEqual(ring.coords[0], ring.coords[4])
        self.assertEqual(ring.coords[0], (0., 0.))
        self.assertTrue(ring.is_ring)
        self.assertEqual(len(polygon.interiors), 0)

        # Create a new polygon from WKB
        data = polygon.wkb
        polygon = None
        ring = None
        polygon = load_wkb(data)
        ring = polygon.exterior
        self.assertEqual(len(ring.coords), 5)
        self.assertEqual(ring.coords[0], ring.coords[4])
        self.assertEqual(ring.coords[0], (0., 0.))
        self.assertTrue(ring.is_ring)
        polygon = None

        # Interior rings (holes)
        polygon = Polygon(coords, [((0.25, 0.25), (0.25, 0.5), (0.5, 0.5),
                                    (0.5, 0.25))])
        self.assertEqual(len(polygon.exterior.coords), 5)
        self.assertEqual(len(polygon.interiors[0].coords), 5)
        with self.assertRaises(IndexError):  # index out of range
            polygon.interiors[1]

        # Test from another Polygon
        copy = Polygon(polygon)
        self.assertEqual(len(polygon.exterior.coords), 5)
        self.assertEqual(len(polygon.interiors[0].coords), 5)
        with self.assertRaises(IndexError):  # index out of range
            polygon.interiors[1]

        # Coordinate getters and setters raise exceptions
        self.assertRaises(NotImplementedError, polygon._get_coords)
        with self.assertRaises(NotImplementedError):
            polygon.coords

        # Geo interface
        self.assertEqual(
            polygon.__geo_interface__, {
                'type':
                'Polygon',
                'coordinates':
                (((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (2.0, -1.0), (0.0, 0.0)),
                 ((0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25),
                  (0.25, 0.25)))
            })

        # Adapter
        hole_coords = [((0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25))]
        pa = asPolygon(coords, hole_coords)
        self.assertEqual(len(pa.exterior.coords), 5)
        self.assertEqual(len(pa.interiors), 1)
        self.assertEqual(len(pa.interiors[0].coords), 5)

        # Test Non-operability of Null rings
        r_null = LinearRing()
        self.assertEqual(r_null.wkt, 'GEOMETRYCOLLECTION EMPTY')
        self.assertEqual(r_null.length, 0.0)

        # Check that we can set coordinates of a null geometry
        r_null.coords = [(0, 0), (1, 1), (1, 0)]
        self.assertAlmostEqual(r_null.length, 3.414213562373095)

        # Error handling
        with self.assertRaises(ValueError):
            # A LinearRing must have at least 3 coordinate tuples
            Polygon([[1, 2], [2, 3]])
示例#15
0
    def get(self):
        p = get_parser.parse_args()
        lon, lat = p['lon'], p['lat']
        if current_app.config['LIMITED_ZONE'] and\
            not Point(lon, lat).intersects(current_app.config['LIMITED_ZONE']):
            #It must be 403, but I don't know how our clients will react:
            return {'data': []}
        self.zupc_customer = cache_single(
            """SELECT id, parent_id, max_distance, insee
               FROM "ZUPC"
               WHERE ST_INTERSECTS(shape, 'POINT(%s %s)')
               AND parent_id = id
               ORDER BY max_distance ASC;""", (lon, lat),
            "zupc_lon_lat",
            lambda v: (v['id'], v['parent_id']),
            get_id=lambda a: (float(a[1].split(",")[0][1:].strip()),
                              float(a[1].split(",")[1][:-1].strip())))
        if len(self.zupc_customer) == 0:
            current_app.logger.debug('No zone found at {}, {}'.format(
                lat, lon))
            return {'data': []}
        zupc_id = self.zupc_customer[0][0]
        zupc_insee = self.zupc_customer[0][3]
        #We can deactivate the max radius for a certain zone
        inactive_filter_period = current_app.config['INACTIVE_FILTER_PERIOD']
        hour = datetime.now().hour
        if inactive_filter_period[0] > inactive_filter_period[1]:
            is_inactive = hour >= inactive_filter_period[0] or\
                    hour <= inactive_filter_period[1]
        else:
            is_inactive = inactive_filter_period[
                0] <= hour <= inactive_filter_period[1]
        if is_inactive:
            max_distance = current_app.config['DEFAULT_MAX_RADIUS']
        else:
            max_distance = min(
                filter(lambda v: v > 0, [v[2] for v in self.zupc_customer]) +
                [current_app.config['DEFAULT_MAX_RADIUS']])
        self.check_freshness()
        g.keys_to_delete = []
        name_redis = '{}:{}:{}'.format(lon, lat, time())
        g.keys_to_delete.append(name_redis)
        #It returns a list of all taxis near the given point
        #For each taxi you have a tuple with: (id, distance, [lat, lon])
        nb_positions = redis_store.georadius(
            current_app.config['REDIS_GEOINDEX_ID'],
            lat,
            lon,
            radius=max_distance / 1000.0,
            units='km',
            storedistkey=name_redis)
        if nb_positions == 0:
            current_app.logger.debug('No taxi found at {}, {}'.format(
                lat, lon))
            return {'data': []}
        self.parent_zupc = {r[0]: r[1] for r in self.zupc_customer}
        self.zupc_customer = {
            r[0]: r[1]
            for r in cache_in(
                'SELECT id, ST_AsBinary(shape) AS shape FROM "ZUPC" WHERE id in %s',
                {int(r1[1])
                 for r1 in self.zupc_customer},
                "zupc_parent_shape",
                lambda v: (v['id'], prep(load_wkb(bytes(v['shape'])))),
                get_id=lambda v: unicode(v[0]))
        }
        taxis = []
        offset = 0
        count = p['count'] * 4
        self.set_not_available(lon, lat, name_redis)
        while len(taxis) < p['count']:
            page_ids_distances = [
                v for v in redis_store.zrangebyscore(name_redis, 0., '+inf',
                                                     offset, count, True)
                if v[0] not in self.not_available
            ]
            offset += count
            if len(page_ids_distances) == 0:
                break
            page_ids = [v[0] for v in page_ids_distances]
            distances = [v[1] for v in page_ids_distances]
            positions = redis_store.geopos(
                current_app.config['REDIS_GEOINDEX_ID'], *page_ids)
            taxis_db = models.RawTaxi.get(page_ids)
            #We get all timestamps
            pipe = redis_store.pipeline()
            map(
                lambda l_taxis: map(
                    lambda t: pipe.zscore(
                        current_app.config['REDIS_TIMESTAMPS'], t['taxi_id'] +
                        ':' + t['u_email']), l_taxis), taxis_db)
            timestamps = pipe.execute()
            #For each member of timestamp_slices we have the first index of the first element
            #in timestamp, and the index of the last element
            #If we have taxis_db = [{t_1,}, {,}, {t_21, t_22}, {t_3,}]
            #Then we want timestamps_slices = [(0, 1), (1, 1), (1, 3), (3, 4)]
            timestamps_slices = []
            map(lambda i: timestamps_slices.append((0, len(i)))\
                if not timestamps_slices\
                else timestamps_slices.append((timestamps_slices[-1][1],
                                               timestamps_slices[-1][1]+len(i))),
                taxis_db)

            l = [
                models.RawTaxi.generate_dict(
                    t[0],
                    None,
                    None,
                    favorite_operator=p['favorite_operator'],
                    position={
                        "lon": t[1][1],
                        "lat": t[1][0]
                    },
                    distance=t[2],
                    timestamps=islice(timestamps, *t[3])) for t in izip(
                        taxis_db, positions, distances, timestamps_slices)
                if len(t) > 0 if self.filter_zone(t[0], t[1])
            ]
            taxis.extend(filter(None, l))
        client = influx_db.get_client(current_app.config['INFLUXDB_TAXIS_DB'])
        if client:
            try:
                client.write_points([{
                    "measurement":
                    "get_taxis_requests",
                    "tags": {
                        "zupc":
                        zupc_insee,
                        "position":
                        "{:.3f}:{:.3f}".format(float(lon), float(lat)),
                        "moteur":
                        current_user.email,
                        "customer":
                        hashlib.sha224(
                            request.headers.getlist("X-Forwarded-For")[0].
                            rpartition(' ')[-1] if 'X-Forwarded-For' in
                            request.headers else request.remote_addr
                            or 'untrackable').hexdigest()[:10]
                    },
                    "time":
                    datetime.utcnow().strftime('%Y%m%dT%H:%M:%SZ'),
                    "fields": {
                        "value": len(taxis)
                    }
                }])
            except Exception as e:
                current_app.logger.error('Influxdb Error: {}'.format(e))
        return {
            'data': sorted(taxis,
                           key=lambda t: t['crowfly_distance'])[:p['count']]
        }
示例#16
0
def transform_wkb_to_form_text(data):
    if data is not None and data is not '':
        return load_wkb(str(data).decode('hex')).to_wkt()
    return ''
示例#17
0
    def get(self):
        p = get_parser.parse_args()
        lon, lat = p['lon'], p['lat']
        if current_app.config['LIMITED_ZONE'] and\
            not Point(lon, lat).intersects(current_app.config['LIMITED_ZONE']):
            #It must be 403, but I don't know how our clients will react:
            return {'data': []}
        self.zupc_customer = db.session.execute(
            """SELECT id, parent_id, max_distance, insee
               FROM "ZUPC"
               WHERE ST_INTERSECTS(shape, 'POINT(:lon :lat)')
               AND parent_id = id
               ORDER BY max_distance ASC;""", {
                "lon": lon,
                "lat": lat
            }).fetchall()
        if len(self.zupc_customer) == 0:
            current_app.logger.debug('No zone found at {}, {}'.format(
                lat, lon))
            return {'data': []}
        zupc_insee = self.zupc_customer[0][3]
        #We can deactivate the max radius for a certain zone
        inactive_filter_period = current_app.config['INACTIVE_FILTER_PERIOD']
        hour = datetime.now().hour
        if inactive_filter_period[0] > inactive_filter_period[1]:
            is_inactive = hour >= inactive_filter_period[0] or\
                    hour <= inactive_filter_period[1]
        else:
            is_inactive = inactive_filter_period[
                0] <= hour <= inactive_filter_period[1]
        if is_inactive:
            max_distance = current_app.config['DEFAULT_MAX_RADIUS']
        else:
            max_distance = min(
                [v
                 for v in [v[2] for v in self.zupc_customer] if v and v > 0] +
                [current_app.config['DEFAULT_MAX_RADIUS']])
        self.check_freshness()
        g.keys_to_delete = []
        name_redis = '{}:{}:{}'.format(lon, lat, time())
        g.keys_to_delete.append(name_redis)
        #It returns a list of all taxis near the given point
        #For each taxi you have a tuple with: (id, distance, [lat, lon])
        nb_positions = redis_store.georadius(
            current_app.config['REDIS_GEOINDEX_ID'],
            lon,
            lat,
            radius=max_distance,
            unit='m',
            store_dist=name_redis)
        if nb_positions == 0:
            current_app.logger.debug('No taxi found at {}, {}'.format(
                lat, lon))
            return {'data': []}
        self.parent_zupc = {r[0]: r[1] for r in self.zupc_customer}
        self.zupc_customer = {
            r[0]: r[1]
            for r in
            [(v[0], prep(load_wkb(bytes(v[1])))) for v in db.session.execute(
                'SELECT id, ST_AsBinary(shape) AS shape FROM "ZUPC" WHERE id in :zupc_list',
                {
                    "zupc_list": tuple((int(r1[1])
                                        for r1 in self.zupc_customer))
                }).fetchall()]
        }
        taxis = []
        offset = 0
        count = p['count'] * 4
        self.set_not_available(lon, lat, name_redis, max_distance)
        while len(taxis) < p['count']:
            page_ids_distances = [
                v for v in redis_store.zrangebyscore(name_redis, 0., '+inf',
                                                     offset, count, True)
                if v[0].decode() not in self.not_available
            ]
            offset += count
            if len(page_ids_distances) == 0:
                break
            page_ids = [v[0].decode() for v in page_ids_distances]
            distances = [v[1] for v in page_ids_distances]
            positions = redis_store.geopos(
                current_app.config['REDIS_GEOINDEX_ID'], *page_ids)
            taxis_db = models.RawTaxi.get(page_ids)
            #We get all timestamps
            pipe = redis_store.pipeline()
            list(
                map(
                    lambda l_taxis: [
                        pipe.zscore(current_app.config['REDIS_TIMESTAMPS'], t[
                            'taxi_id'] + ':' + t['u_email']) for t in l_taxis
                    ], taxis_db))
            timestamps = pipe.execute()
            #For each member of timestamp_slices we have the first index of the first element
            #in timestamp, and the index of the last element
            #If we have taxis_db = [{t_1,}, {,}, {t_21, t_22}, {t_3,}]
            #Then we want timestamps_slices = [(0, 1), (1, 1), (1, 3), (3, 4)]
            timestamps_slices = []
            list(map(lambda i: timestamps_slices.append((0, len(i)))\
                if not timestamps_slices\
                else timestamps_slices.append((timestamps_slices[-1][1],
                                               timestamps_slices[-1][1]+len(i))),
                taxis_db))
            l = [
                models.RawTaxi.generate_dict(
                    t[0],
                    None,
                    None,
                    favorite_operator=p['favorite_operator'],
                    position={
                        "lon": t[1][0],
                        "lat": t[1][1]
                    },
                    distance=t[2],
                    timestamps=islice(timestamps, *t[3]))
                for t in zip(taxis_db, positions, distances, timestamps_slices)
                if len(t) > 0 if self.filter_zone(t[0], t[1])
            ]
            taxis.extend([_f for _f in l if _f])

        influx_db.write_point(
            current_app.config['INFLUXDB_TAXIS_DB'],
            "get_taxis_requests", {
                "zupc":
                zupc_insee,
                "position":
                "{:.3f}:{:.3f}".format(float(lon), float(lat)),
                "moteur":
                current_user.email,
                "customer":
                hashlib.sha224(
                    str((request.headers.getlist("X-Forwarded-For")
                         [0].rpartition(' ')[-1] if 'X-Forwarded-For'
                         in request.headers else request.remote_addr)
                        or 'untrackable').encode('utf-8')).hexdigest()[:10]
            },
            value=len(taxis))
        return {
            'data': sorted(taxis,
                           key=lambda t: t['crowfly_distance'])[:p['count']]
        }
示例#18
0
    def test_polygon(self):

        # Initialization
        # Linear rings won't usually be created by users, but by polygons
        coords = ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0))
        ring = LinearRing(coords)
        self.assertEqual(len(ring.coords), 5)
        self.assertEqual(ring.coords[0], ring.coords[4])
        self.assertEqual(ring.coords[0], ring.coords[-1])
        self.assertTrue(ring.is_ring)

        # Coordinate modification
        ring.coords = ((0.0, 0.0), (0.0, 2.0), (2.0, 2.0), (2.0, 0.0))
        self.assertEqual(
            ring.__geo_interface__,
            {'type': 'LinearRing',
             'coordinates': ((0.0, 0.0), (0.0, 2.0), (2.0, 2.0), (2.0, 0.0),
                             (0.0, 0.0))})

        # Test ring adapter
        coords = [[0.0, 0.0], [0.0, 1.0], [1.0, 1.0], [1.0, 0.0]]
        ra = asLinearRing(coords)
        self.assertTrue(ra.wkt.upper().startswith('LINEARRING'))
        self.assertEqual(dump_coords(ra),
                         [(0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0),
                          (0.0, 0.0)])
        coords[3] = [2.0, -1.0]
        self.assertEqual(dump_coords(ra),
                         [(0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (2.0, -1.0),
                          (0.0, 0.0)])

        # Construct a polygon, exterior ring only
        polygon = Polygon(coords)
        self.assertEqual(len(polygon.exterior.coords), 5)

        # Ring Access
        self.assertIsInstance(polygon.exterior, LinearRing)
        ring = polygon.exterior
        self.assertEqual(len(ring.coords), 5)
        self.assertEqual(ring.coords[0], ring.coords[4])
        self.assertEqual(ring.coords[0], (0., 0.))
        self.assertTrue(ring.is_ring)
        self.assertEqual(len(polygon.interiors), 0)

        # Create a new polygon from WKB
        data = polygon.wkb
        polygon = None
        ring = None
        polygon = load_wkb(data)
        ring = polygon.exterior
        self.assertEqual(len(ring.coords), 5)
        self.assertEqual(ring.coords[0], ring.coords[4])
        self.assertEqual(ring.coords[0], (0., 0.))
        self.assertTrue(ring.is_ring)
        polygon = None

        # Interior rings (holes)
        polygon = Polygon(coords, [((0.25, 0.25), (0.25, 0.5),
                                    (0.5, 0.5), (0.5, 0.25))])
        self.assertEqual(len(polygon.exterior.coords), 5)
        self.assertEqual(len(polygon.interiors[0].coords), 5)
        with self.assertRaises(IndexError):  # index out of range
            polygon.interiors[1]

        # Test from another Polygon
        copy = Polygon(polygon)
        self.assertEqual(len(polygon.exterior.coords), 5)
        self.assertEqual(len(polygon.interiors[0].coords), 5)
        with self.assertRaises(IndexError):  # index out of range
            polygon.interiors[1]

        # Coordinate getters and setters raise exceptions
        self.assertRaises(NotImplementedError, polygon._get_coords)
        with self.assertRaises(NotImplementedError):
            polygon.coords

        # Geo interface
        self.assertEqual(
            polygon.__geo_interface__,
            {'type': 'Polygon',
             'coordinates': (((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (2.0, -1.0),
                             (0.0, 0.0)), ((0.25, 0.25), (0.25, 0.5),
                             (0.5, 0.5), (0.5, 0.25), (0.25, 0.25)))})

        # Adapter
        hole_coords = [((0.25, 0.25), (0.25, 0.5), (0.5, 0.5), (0.5, 0.25))]
        pa = asPolygon(coords, hole_coords)
        self.assertEqual(len(pa.exterior.coords), 5)
        self.assertEqual(len(pa.interiors), 1)
        self.assertEqual(len(pa.interiors[0].coords), 5)

        # Test Non-operability of Null rings
        r_null = LinearRing()
        self.assertEqual(r_null.wkt, 'GEOMETRYCOLLECTION EMPTY')
        self.assertEqual(r_null.length, 0.0)

        # Check that we can set coordinates of a null geometry
        r_null.coords = [(0, 0), (1, 1), (1, 0)]
        self.assertAlmostEqual(r_null.length, 3.414213562373095)

        # Error handling
        with self.assertRaises(ValueError):
            # A LinearRing must have at least 3 coordinate tuples
            Polygon([[1, 2], [2, 3]])
示例#19
0
文件: taxi.py 项目: xkantsu/APITaxi
    def get(self):
        p = get_parser.parse_args()
        lon, lat = p['lon'], p['lat']
        if current_app.config['LIMITED_ZONE'] and\
            not Point(lon, lat).intersects(current_app.config['LIMITED_ZONE']):
            #It must be 403, but I don't know how our clients will react:
            return {'data': []}
        self.zupc_customer = cache_single("""SELECT id, parent_id FROM "ZUPC"
                            WHERE ST_INTERSECTS(shape, 'POINT(%s %s)');""",
                            (lon, lat), "zupc_lon_lat",
                            lambda v: (v['id'], v['parent_id']),
                            get_id=lambda a:(float(a[1].split(",")[0][1:].strip()),
                                             float(a[1].split(",")[1][:-1].strip())))
        if len(self.zupc_customer) == 0:
            current_app.logger.debug('No zone found at {}, {}'.format(lat, lon))
            return {'data': []}
        self.check_freshness()
        g.keys_to_delete = []
        name_redis = '{}:{}:{}'.format(lon, lat, time())
        g.keys_to_delete.append(name_redis)
        #It returns a list of all taxis near the given point
        #For each taxi you have a tuple with: (id, distance, [lat, lon])
        nb_positions = redis_store.georadius(current_app.config['REDIS_GEOINDEX_ID'],
                lat, lon, storedistkey=name_redis)
        if nb_positions == 0:
            current_app.logger.debug('No taxi found at {}, {}'.format(lat, lon))
            return {'data': []}
        self.parent_zupc = {r[0]: r[1] for r in self.zupc_customer}
        self.zupc_customer = {r[0]: r[1]
          for r in cache_in(
              'SELECT id, ST_AsBinary(shape) AS shape FROM "ZUPC" WHERE id in %s',
               {int(r1[1]) for r1 in self.zupc_customer}, "zupc_parent_shape",
               lambda v: (v['id'], prep(load_wkb(bytes(v['shape'])))),
              get_id=lambda v:unicode(v[0]))}
        taxis = []
        offset = 0
        count = p['count'] * 4
        self.set_not_available(lon, lat, name_redis)
        while len(taxis) < p['count']:
            page_ids_distances = [v for v in redis_store.zrangebyscore(name_redis, 0., '+inf',
                                    offset, count, True) if v[0] not in self.not_available]
            offset += count
            if len(page_ids_distances) == 0:
                break
            page_ids = [v[0] for v in page_ids_distances]
            distances = [v[1] for v in page_ids_distances]
            positions = redis_store.geopos(current_app.config['REDIS_GEOINDEX_ID']
                                           ,*page_ids)
            taxis_db = taxis_models.RawTaxi.get(page_ids)
#We get all timestamps
            pipe = redis_store.pipeline()
            map(lambda l_taxis:map(
                lambda t: pipe.zscore(current_app.config['REDIS_TIMESTAMPS'],
                                      t['taxi_id']+':'+t['u_email']),l_taxis)
                , taxis_db)
            timestamps = pipe.execute()
#If we have taxis_db = [{t_1}, {}, {t_21, t_22}, {t_3}]
#Then we want timestamps_slices = [(0, 1), (1, 1), (1, 3), (3, 4)]
            timestamps_slices = []
            map(lambda i: timestamps_slices.append((0, len(i)))\
                if not timestamps_slices\
                else timestamps_slices.append((timestamps_slices[-1][1],
                                               timestamps_slices[-1][1]+len(i))),
                taxis_db)

            l = [taxis_models.RawTaxi.generate_dict(t[0],
                        None, None,
                        favorite_operator=p['favorite_operator'],
                        position={"lon": t[1][1], "lat": t[1][0]},
                        distance=t[2], timestamps=islice(timestamps, *t[3]))
                for t in izip(taxis_db, positions, distances, timestamps_slices) if len(t) > 0
                if self.filter_zone(t[0], t[1])]
            taxis.extend(filter(None, l))
        return {'data': sorted(taxis, key=lambda t: t['crowfly_distance'])[:p['count']]}