-
Notifications
You must be signed in to change notification settings - Fork 57
Add GeoPackage data format #709
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 4 commits
415713a
dd00081
b9e724c
a1998f7
7ce7535
973d27c
e8cc15c
aace235
4300039
74a680d
ba9a184
7c849c7
89adb49
dd2657a
340323d
15412fb
822a304
793b349
fa77f92
0d77c6c
161d681
c8f0c31
d62ac7a
8522e1d
4aab3f9
15e6ddd
8f9df16
9ba4e68
a0ceb1b
6d8fde2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ import { | |
SourceType | ||
} from '@jupytergis/schema'; | ||
import RASTER_LAYER_GALLERY from '../rasterlayer_gallery/raster_layer_gallery.json'; | ||
import { GeoPackageAPI } from '@ngageoint/geopackage'; | ||
|
||
export const debounce = ( | ||
func: CallableFunction, | ||
|
@@ -489,6 +490,31 @@ export const loadGeoTiff = async ( | |
}; | ||
}; | ||
|
||
/** | ||
* Read a GeoPackage file | ||
* | ||
* @param file The GeoPackage file content as an ArrayBuffer | ||
* | ||
* @returns A promise that resolves to a GeoJSON FeatureCollection | ||
* | ||
*/ | ||
const loadGeoPackageFile = async (file: ArrayBuffer) => { | ||
const bytes = new Uint8Array(file); | ||
const gpkg = await GeoPackageAPI.open(bytes); | ||
|
||
const tables = gpkg.getFeatureTables(); | ||
const features: GeoJSON.Feature[] = []; | ||
for (const tableName of tables) { | ||
const dao = gpkg.getFeatureDao(tableName); | ||
const bbox = dao.getBoundingBox(); | ||
const iter = gpkg.queryForGeoJSONFeaturesInTable(tableName, bbox); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure how I feel about converting the data to GeoJSON. Have you looked in to https://github.com/richard-thomas/ol-load-geopackage ? (I'm not sure how it works under the hood, maybe it loads from GeoJSON too 😆 ) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now we are using the library you suggested for vector layers, but for raster layers we're still using ngageoint |
||
for (const feat of iter) { | ||
features.push(feat); | ||
} | ||
} | ||
return { type: 'FeatureCollection', features }; | ||
}; | ||
|
||
/** | ||
* Generalized file reader for different source types. | ||
* | ||
|
@@ -570,6 +596,30 @@ export const loadFile = async (fileInfo: { | |
throw new Error(`Failed to fetch ${filepath}`); | ||
} | ||
|
||
case 'GeoPackageSource': { | ||
const cached = await getFromIndexedDB(filepath); | ||
if (cached) { | ||
return cached.file; | ||
} | ||
|
||
const geojson = await fetchWithProxies( | ||
filepath, | ||
model, | ||
async response => { | ||
const arrayBuffer = await response.arrayBuffer(); | ||
return await loadGeoPackageFile(arrayBuffer); | ||
} | ||
); | ||
|
||
if (geojson) { | ||
await saveToIndexedDB(filepath, geojson); | ||
return geojson; | ||
} | ||
|
||
showErrorMessage('Network error', `Failed to fetch ${filepath}`); | ||
throw new Error(`Failed to fetch ${filepath}`); | ||
} | ||
|
||
default: { | ||
throw new Error(`Unsupported URL handling for source type: ${type}`); | ||
} | ||
|
@@ -636,6 +686,15 @@ export const loadFile = async (fileInfo: { | |
} | ||
} | ||
|
||
case 'GeoPackageSource': { | ||
if (typeof file.content === 'string') { | ||
const arrayBuffer = await stringToArrayBuffer(file.content); | ||
return await loadGeoPackageFile(arrayBuffer); | ||
} else { | ||
throw new Error('Invalid file format for GeoPackage content.'); | ||
} | ||
} | ||
|
||
default: { | ||
throw new Error(`Unsupported source type: ${type}`); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"type": "object", | ||
"description": "GeoPackageSource", | ||
"title": "IGeoPackageSource", | ||
"required": ["path"], | ||
"additionalProperties": false, | ||
"properties": { | ||
"path": { | ||
"type": "string", | ||
"description": "The path to the GeoPackage source" | ||
}, | ||
"attribution": { | ||
"type": "string", | ||
"readOnly": true, | ||
"description": "The attribution for the GeoPackage source.", | ||
"default": "" | ||
}, | ||
"projection": { | ||
"type": "string", | ||
"description": "The projection information for the GeoPackage data (optional).", | ||
"default": "EPSG:4326" | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
declare module '*.wasm' { | ||
const url: string; | ||
export default url; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, the user should get a chance to choose which table(s) they want to load. Maybe that could be a future PR though :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Users are now able to choose which tables to load