Skip to content
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

Example: Create a new GeoPackage #185

Open
bertday opened this issue Dec 24, 2022 · 2 comments
Open

Example: Create a new GeoPackage #185

bertday opened this issue Dec 24, 2022 · 2 comments

Comments

@bertday
Copy link

bertday commented Dec 24, 2022

Hello — thank you for this awesome library!

I am a new user and would like to know how to create a new, empty GeoPackage. I'm having some trouble hunting down an example of how to do this. I see there a method GeoPackageAPI.create(), but it's not entirely clear to me how to use it. When I run this code:

import { GeoPackageAPI } from '@ngageoint/geopackage';

(async () => {
  const gpkg = await GeoPackageAPI.create('/Users/me/test.gpkg');
})(); 

I get Error: Unable to initialize canvas.

Having a minimal example of this would be super helpful — thank you!

@danbritt
Copy link

In the docs for using it with node, it says you have to import setCanvasKitWasmLocateFile and then use it and return the path to the file like this

setCanvasKitWasmLocateFile(file => 'path/to/geopackage/dist/canvaskit/' + file);

Your example would change to:

import { GeoPackageAPI, setCanvasKitWasmLocateFile } from '@ngageoint/geopackage';

(async () => {
  setCanvasKitWasmLocateFile(file => 'path/to/geopackage/dist/canvaskit/' + file);
  const gpkg = await GeoPackageAPI.create('/Users/me/test.gpkg');
})();

However, I have done this and it still doesn't work. I still get Error: Unable to initialize canvas. So I'm not sure if something is broken or what. I have even returned the full absolute path to the canvaskit.wasm file and it still says it can't initialize.

@danbritt
Copy link

So it looks like you don't need the canvas stuff if all you want is to create a geopackage with geojson features in it, which is what I needed to do. You can just make it think it's initialized by using CanvasKitCanvasAdapter.initialized = true;. Here is an example:

index.mjs

import geoJson from './geoJson.json' assert { type: 'json' };
import {
    GeoPackageAPI,
    FeatureColumn,
    GeometryColumns,
    GeoPackageDataType,
    BoundingBox,
    GeometryType,
    CanvasKitCanvasAdapter,
} from '@ngageoint/geopackage';

(async () => {
	// Fake that the canvas is initialized, since it doesn't seem to initialize in a node environment
	CanvasKitCanvasAdapter.initialized = true;
	
	
	const gpkg = await GeoPackageAPI.create('./test.gpkg');
	
	// Check GeoPackageDataType enum for these values
	let fields = [
		{ name: 'ID', typeName: 'TEXT' },
		{ name: 'Count', typeName: 'INT' },
		{ name: 'ItemNumber', typeName: 'TEXT' }
	];
	
	let geomTypeName = 'POINT'; // Check GeometryType enum for these values 
	let tableName = 'MyLayer';
	let srId = 4326;
	let geomColName = 'SHAPE';
	let geomTypeId = GeometryType.fromName(geomTypeName);
	
	let geometryColumns = new GeometryColumns();
	geometryColumns.table_name = tableName;
	geometryColumns.column_name = geomColName;
	geometryColumns.geometry_type_name = geomTypeName;
	geometryColumns.z = 2;
	geometryColumns.m = 2;
	
	let columns = [];
	// Need to create an int auto increment ID for the sqlite db. Not sure if it can use guids
	columns.push(FeatureColumn.createPrimaryKeyColumn(0, 'NID', true));
	columns.push(
		FeatureColumn.createGeometryColumn(
			1,
			'SHAPE',
			geomTypeId,
			true,
			null
		)
	);
	let colIndex = 2;
	
	// Add other columns
	for (let field of fields) {
		let fieldTypeId = GeoPackageDataType.fromName(field.typeName);

		columns.push(
			FeatureColumn.createColumn(
				colIndex,
				field.name,
				fieldTypeId,
				false,
				null
			)
		);
		colIndex++;
	}

	let bbox = new BoundingBox(-180, 180, -90, 90);
	
	gpkg.createFeatureTable(
		tableName,
		geometryColumns,
		columns,
		bbox,
		srId
	);
	
	await gpkg.addGeoJSONFeaturesToGeoPackage(
		geoJson.features,
		tableName
	);
	
	gpkg.close();
	
})();

geoJson.json

{
   "type":"FeatureCollection",
   "features":[
      {
         "type":"Feature",
         "geometry":{
            "type":"Point",
            "coordinates":[
               -84.336016,
               35.906206
            ]
         },
         "properties":{
            "ID":"97bbf51e-0262-4439-a217-00b3dc282bdc",
            "Count":2,
            "ItemNumber":"Item1"
         }
      },
      {
         "type":"Feature",
         "geometry":{
            "type":"Point",
            "coordinates":[
               -84.386671,
               35.943449
            ]
         },
         "properties":{
            "ID":"9642775c-3dee-4906-8411-8040e9f3329c",
            "Count":1,
            "ItemNumber":"Item2"
         }
      },
      {
         "type":"Feature",
         "geometry":{
            "type":"Point",
            "coordinates":[
               -84.301242,
               35.943728
            ]
         },
         "properties":{
            "ID":"022d12fa-f156-4ca4-9713-e5df67c078ee",
            "Count":4,
            "ItemNumber":"Item3"
         }
      },
      {
         "type":"Feature",
         "geometry":{
            "type":"Point",
            "coordinates":[
               -84.360066,
               35.950069
            ]
         },
         "properties":{
            "ID":"98841440-789b-4441-9640-b00cc1405e75",
            "Count":8,
            "ItemNumber":"Item4"
         }
      },
      {
         "type":"Feature",
         "geometry":{
            "type":"Point",
            "coordinates":[
               -84.317448,
               35.914034
            ]
         },
         "properties":{
            "ID":"f2af3539-697a-454a-a484-0b8978556f4e",
            "COUNT":11,
            "ItemNumber":"Item5"
         }
      }
   ],
   "totalFeatures":5,
   "numberMatched":5,
   "numberReturned":5,
   "timeStamp":"2023-01-19T04:19:42.308Z",
   "crs":{
      "type":"name",
      "properties":{
         "name":"urn:ogc:def:crs:EPSG::4326"
      }
   }
}

These are the resources I used to figure this out:

Example: https://github.com/ngageoint/geopackage-csv-js/blob/main/index.ts

Useful Docs:
https://ngageoint.github.io/geopackage-js/api/modules/GeometryType.html
https://ngageoint.github.io/geopackage-js/api/enums/GeometryType.html
https://ngageoint.github.io/geopackage-js/api/modules/GeoPackageDataType.html
https://ngageoint.github.io/geopackage-js/api/enums/GeoPackageDataType.html
https://ngageoint.github.io/geopackage-js/api/classes/GeometryColumns.html
https://ngageoint.github.io/geopackage-js/api/classes/FeatureColumn.html
https://ngageoint.github.io/geopackage-js/api/classes/GeoPackage.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants