예제 #1
0
def issues_mvt(db, z, x, y, format):
    lon1, lat2 = tiles.tile2lonlat(x, y, z)
    lon2, lat1 = tiles.tile2lonlat(x + 1, y + 1, z)
    dlon = (lon2 - lon1) / 256
    dlat = (lat2 - lat1) / 256

    params = Params(max_limit=50 if z > 18 else 10000)
    params.tilex = x
    params.tiley = y
    params.zoom = z
    params.lat = None
    params.lon = None
    params.full = False

    if params.zoom > 18:
        return
    if (not params.users) and (not params.source) and (params.zoom < 7):
        return

    results = query._gets(db, params) if z >= 7 else None

    if format == 'mvt':
        tile = _errors_mvt(db, results, z, lon1, lat1, lon2, lat2,
                           params.limit)
        if tile:
            response.content_type = 'application/vnd.mapbox-vector-tile'
            return tile
        else:
            return HTTPError(404)
    elif format in ('geojson', 'json'):  # Fall back to GeoJSON
        tile = _errors_geojson(db, results, z, lon1, lat1, lon2, lat2,
                               params.limit)
        if tile:
            response.content_type = 'application/vnd.geo+json'
            return tile
        else:
            return []
    else:
        return HTTPError(404)
예제 #2
0
def heat(db, z, x, y):
    COUNT = 32

    lon1, lat2 = tiles.tile2lonlat(x, y, z)
    lon2, lat1 = tiles.tile2lonlat(x + 1, y + 1, z)

    params = Params()
    items = query._build_where_item(params.item, "items")
    params.tilex = x
    params.tiley = y
    params.zoom = z
    params.lat = None
    params.lon = None

    if params.zoom > 18:
        return

    db.execute("""
SELECT
    SUM((SELECT SUM(t) FROM UNNEST(number) t))
FROM
    items
WHERE
""" + items)
    limit = db.fetchone()
    if limit and limit[0]:
        limit = float(limit[0])
    else:
        return HTTPError(404)

    join, where = query._build_param(db,
                                     None,
                                     params.source,
                                     params.item,
                                     params.level,
                                     params.users,
                                     params.classs,
                                     params.country,
                                     params.useDevItem,
                                     params.status,
                                     params.tags,
                                     params.fixable,
                                     tilex=params.tilex,
                                     tiley=params.tiley,
                                     zoom=params.zoom)
    join = join.replace("%", "%%")
    where = where.replace("%", "%%")

    sql = """
SELECT
    COUNT(*),
    ((lon-%(lon1)s) * %(count)s / (%(lon2)s-%(lon1)s) + 0.5)::int AS latn,
    ((lat-%(lat1)s) * %(count)s / (%(lat2)s-%(lat1)s) + 0.5)::int AS lonn,
    mode() WITHIN GROUP (ORDER BY items.marker_color) AS color
FROM
""" + join + """
WHERE
""" + where + """
GROUP BY
    latn,
    lonn
"""
    db.execute(sql, {
        "lon1": lon1,
        "lat1": lat1,
        "lon2": lon2,
        "lat2": lat2,
        "count": COUNT
    })

    features = []
    for row in db.fetchall():
        count, x, y, color = row
        count = max(
            int(
                math.log(count) /
                math.log(limit / ((z - 4 + 1 + math.sqrt(COUNT))**2)) * 255),
            1 if count > 0 else 0)
        if count > 0:
            count = 255 if count > 255 else count
            features.append({
                "geometry":
                Polygon([(x, y), (x - 1, y), (x - 1, y - 1), (x, y - 1)]),
                "properties": {
                    "color": int(color[1:], 16),
                    "count": count
                }
            })

    response.content_type = 'application/vnd.mapbox-vector-tile'
    return mapbox_vector_tile.encode([{
        "name": "issues",
        "features": features
    }],
                                     extents=COUNT)