def _load_polygon(big_endian, type_bytes, data_bytes): endian_token = '>' if big_endian else '<' data_bytes = iter(data_bytes) is_m = False if type_bytes in WKB_2D.values(): num_dims = 2 elif type_bytes in WKB_Z.values(): num_dims = 3 elif type_bytes in WKB_M.values(): num_dims = 3 is_m = True elif type_bytes in WKB_ZM.values(): num_dims = 4 coords = [] [num_rings] = struct.unpack('%sl' % endian_token, as_bin_str(take(4, data_bytes))) while True: ring = [] [num_verts] = struct.unpack('%sl' % endian_token, as_bin_str(take(4, data_bytes))) verts_wkb = as_bin_str(take(8 * num_verts * num_dims, data_bytes)) verts = block_splitter(verts_wkb, 8) if six.PY2: verts = (b''.join(x) for x in verts) elif six.PY3: verts = (b''.join(bytes([y]) for y in x) for x in verts) for vert_wkb in block_splitter(verts, num_dims): values = [ struct.unpack('%sd' % endian_token, x)[0] for x in vert_wkb ] if is_m: values.insert(2, 0.0) ring.append(values) coords.append(ring) if len(coords) == num_rings: break return dict(type='Polygon', coordinates=coords)
def __load_linestring(big_endian, type_bytes, data_bytes): endian_token = '>' if big_endian else '<' num_vals = int(len(data_bytes) / 8) # 8 bytes per float val values = struct.unpack('%s%s' % (endian_token, 'd' * num_vals), data_bytes) if type_bytes == WKB_2D['LineString']: coords = block_splitter(values, 2) elif type_bytes == WKB_Z['LineString']: coords = block_splitter(values, 3) elif type_bytes == WKB_M['LineString']: coords = block_splitter(values, 3) # For the M type geometry, insert values of 0.0 for Z # This effectively converts a M type geometry into a ZM. coords = ([x, y, 0.0, m] for x, y, m in coords) elif type_bytes == WKB_ZM['LineString']: coords = block_splitter(values, 4) return dict(type='LineString', coordinates=list(coords))
def _load_polygon(big_endian, type_bytes, data_bytes): endian_token = '>' if big_endian else '<' data_bytes = iter(data_bytes) is_m = False if type_bytes in WKB_2D.values(): num_dims = 2 elif type_bytes in WKB_Z.values(): num_dims = 3 elif type_bytes in WKB_M.values(): num_dims = 3 is_m = True elif type_bytes in WKB_ZM.values(): num_dims = 4 coords = [] [num_rings] = struct.unpack('%sl' % endian_token, as_bin_str(take(4, data_bytes))) while True: ring = [] [num_verts] = struct.unpack('%sl' % endian_token, as_bin_str(take(4, data_bytes))) verts_wkb = as_bin_str(take(8 * num_verts * num_dims, data_bytes)) verts = block_splitter(verts_wkb, 8) if six.PY2: verts = (b''.join(x) for x in verts) elif six.PY3: verts = (b''.join(bytes([y]) for y in x) for x in verts) for vert_wkb in block_splitter(verts, num_dims): values = [struct.unpack('%sd' % endian_token, x)[0] for x in vert_wkb] if is_m: values.insert(2, 0.0) ring.append(values) coords.append(ring) if len(coords) == num_rings: break return dict(type='Polygon', coordinates=coords)
def __load_linestring(big_endian, type_bytes, data_bytes): endian_token = '>' if big_endian else '<' num_vals = len(data_bytes) / 8 # 8 bytes per float val values = struct.unpack('%s%s' % (endian_token, 'd' * num_vals), data_bytes) if type_bytes == WKB_2D['LineString']: coords = block_splitter(values, 2) elif type_bytes == WKB_Z['LineString']: coords = block_splitter(values, 3) elif type_bytes == WKB_M['LineString']: coords = block_splitter(values, 3) # For the M type geometry, insert values of 0.0 for Z # This effectively converts a M type geometry into a ZM. coords = ([x, y, 0.0, m] for x, y, m in coords) elif type_bytes == WKB_ZM['LineString']: coords = block_splitter(values, 4) return dict(type='LineString', coordinates=list(coords))
def _load_multilinestring(big_endian, type_bytes, data_bytes): endian_token = '>' if big_endian else '<' data_bytes = iter(data_bytes) is_m = False if type_bytes in WKB_2D.values(): num_dims = 2 elif type_bytes in WKB_Z.values(): num_dims = 3 elif type_bytes in WKB_M.values(): num_dims = 3 is_m = True elif type_bytes in WKB_ZM.values(): num_dims = 4 if is_m: dim = 'M' else: dim = _INT_TO_DIM_LABEL[num_dims] [num_ls] = struct.unpack('%sl' % endian_token, as_bin_str(take(4, data_bytes))) coords = [] while True: ls_endian = as_bin_str(take(1, data_bytes)) ls_type = as_bin_str(take(4, data_bytes)) if big_endian: assert ls_endian == BIG_ENDIAN assert ls_type == _WKB[dim]['LineString'] else: assert ls_endian == LITTLE_ENDIAN assert ls_type[::-1] == _WKB[dim]['LineString'] [num_verts] = struct.unpack('%sl' % endian_token, as_bin_str(take(4, data_bytes))) num_values = num_dims * num_verts values = struct.unpack(endian_token + 'd' * num_values, as_bin_str(take(8 * num_values, data_bytes))) values = list(block_splitter(values, num_dims)) if is_m: for v in values: v.insert(2, 0.0) coords.append(values) if len(coords) == num_ls: break return dict(type='MultiLineString', coordinates=coords)