Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
interface IDocumentInfo {
geodidid: string;
documentVal: any;
parentid?: string;
}interface IDocumentInfo {
geodidid: string;
documentVal: any;
parentid?: string;
}interface IPinInfo {
geodidid: string;
cid: string;
pinDate: Date;
token: string
} interface LoadInfo {
documentInfo: IDocumentInfo;
powergateInstance: Powergate
}Astral - Building tools to enable the location-based decentralized web.
# sample post with curl
export PROVIDER_PASS=<provider password>
export HOST=https://<host>/api
eval "$(jq -M -r '@sh "ACCESS_TOKEN=\(.tokenData.token)"' <<< "$(curl -H 'Content-Type: application/json' -X POST -d '{"email":"provider@iwahi.com","password":"'"$PROVIDER_PASS"'"}' $HOST/53f889/2cfae1)")"
echo $ACCESS_TOKEN
curl -s \
-w '\n' \
-H "Content-Type: application/json" \
-H "x-access-token: $ACCESS_TOKEN" \
$HOST/94cbae/4d46c9 \
-d '{"metadata":
{"location": {"geometries": [
{
"coordinates": [
-73.9132,
40.68405
],
"type": "Point"
}
],
"type": "GeometryCollection"
},
"model": "mri-esm2-ssp126",
"project_id": "proj_29lo8RFQiVowh4u5WHdbFSLKExL",
"provider": "tSuqRPkLVfDqQG3mgr0x4",
"source": "station xxxxx"
},
"ts": "'"`date +"%Y-%m-%dT%H:%M:%S%z"`"'",
"measurements": [
{
"type": "T",
"unit": "C",
"value": 20
},
{
"type": "H",
"unit": "P",
"value": 30
}
]
}'
# return value, with id/data hash:
{"geots":{"_id":"tcXoR-E50jQg-j3iUapcS","metadata":{"source":"station xxxxx","model":"mri-esm2-ssp126","project_id":"proj_29lo8RFQiVowh4u5WHdbFSLKExL","anchor":null,"ip":"127.0.0.1","provider":{"_id":"tSuqRPkLVfDqQG3mgr0x4","name":"Sample Provider","path":"4818b0","id":"tSuqRPkLVfDqQG3mgr0x4"},"location":{"type":"GeometryCollection","geometries":[{"type":"Point","coordinates":[-73.9132,40.68405]}]}},"ts":"2022-09-07T20:21:10.000Z","measurements":[{"type":"T","unit":"C","value":20},{"type":"H","unit":"P","value":30}],"hash":"3a968d77d2864f6c5e85d287fa8c7c9b12d04dfef5956f03b7ee4218bf8b4076","__v":0}}




{
"gbsuv" => {1, 2, 3}
"gbsuv7" => {1, 2, 3}
"gbsuv7d" => {1}
"gbsuv7dg" => {1}
"gbsuv7z" => {2, 3}
"gbsuv7zw" => {2}
"gbsuv7zy" => {3}
}Geospatial Non-fungible Token

Ecological IndexEcological IndexEcological Index{
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
type: "Polygon",
coordinates: [
[
[-68.8906744122505, 12.147418397582491],
[-68.8907468318939, 12.147347599447487],
[-68.8907213509083, 12.14723615790054],
[-68.8905939459801, 12.147198136656193],
[-68.89051884412766, 12.147280734524921],
[-68.89055103063583, 12.147379065287602],
[-68.8906744122505, 12.147418397582491],
],
],
},
},
],
}struct EcologicalIndex {
string indexType;
int256 indexValue;
}bytes constant SIN_TABLE = "\x00\x00\x00\x00\x00\xc9\x0f\x88\x01"; //truncated for readabilityWhat exactly *is* spatial data?



img = [[ 1, 0, 1 ],
[ 0, 1, 0 ],
[ 1, 0, 1 ]]Weekly updates from the Astral team
Introduction
point = [ 45.841616, 6.212074 ]
line = [[ -0.131838, 51.52241 ],
[ -3.142085, 51.50190 ],
[ -3.175046, 55.96150 ]]
polygon = [[[ -43.06640, 17.47643 ],
[ -46.40625, 10.83330 ],
[ -37.26562, 11.52308 ],
[ -43.06640, 17.47643 ]]]
# ^^ The first and last coordinate are the same {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-0.0986060,
51.5326047
],
[
-78.639101,
35.7803929
],
[
-8.6094188,
41.1398493
],
[
-0.0986060,
51.5326047
]
]
]
}
}
Framing our work at Astral
# sample analytics query:
# query one month's 3 hourly data for a polygon and provider, return average temperature.
export HOST=https://<host>.com/api
curl -s \
-w '\n' \
-G \
-H "Content-Type: application/json" \
-d 'polygon={"type":"Polygon","coordinates":[[[-3.7025,40.4165],[3,60],[6,90],[-3.7025,40.4165]]]}' \
-d 'startdate=2019-01-01' \
-d 'enddate=2019-01-02' \
-d 'providerId=tSuqRPkLVfDqQG3mgr0x4' \
$HOST/596090/00833a
# raw data on which above query is based:
curl -s \
-w '\n' \
-G \
-H "Content-Type: application/json" \
-d 'polygon={"type":"Polygon","coordinates":[[[-3.7025,40.4165],[3,60],[6,90],[-3.7025,40.4165]]]}' \
-d 'startdate=2019-01-01' \
-d 'enddate=2019-01-02' \
-d 'providerId=tSuqRPkLVfDqQG3mgr0x4' \
$HOST/596090/7afb79

degreesToNanoradians.Smart contracts for raster and vector spatial data assets
const url = 'http://download.osgeo.org/geotiff/samples/gdal_eg/cea.tif';
// First create instance of IPFS
const ipfs: IPFS = await create();
// Request TIFF from Endpoint
const image = await getImageFromUrl(url);
// Start the tiling and encoding process
const ires: IResponse = await startTile(ipfs, image);zoneContains(zoneID, coordinates) returns (bool)`{
'0,240,120,360': {
window: [ 0, 240, 120, 360 ],
cid: CID(bafyreihdsnkivmftr64zgv23aso4eseikqlqkznrcgtmkjd4hybno2nk7i),
data: Uint8Array(14404) [
129, 89, 56, 64, 0, 41, 33, 58, 82, 115, 41, 74,
99, 90, 90, 58, 25, 82, 66, 82, 74, 16, 58, 74,
74, 66, 66, 66, 0, 66, 82, 66, 115, 197, 107, 82,
107, 90, 90, 107, 115, 82, 74, 58, 25, 0, 25, 8,
16, 33, 25, 107, 82, 74, 99, 90, 107, 82, 49, 66,
123, 90, 82, 58, 82, 115, 16, 25, 16, 25, 8, 33,
41, 58, 107, 82, 123, 107, 82, 90, 25, 33, 82, 66,
41, 0, 33, 25, 16, 25, 49, 99, 74, 58, 25, 49,
99, 74, 74, 90,
... 14304 more items
],
tileSize: { width: 120, height: 120 }
},
'120,240,240,360': {
window: [ 120, 240, 240, 360 ],
cid: CID(bafyreiczb6y3ogyyvxuw5jpcfuumrn7mnxwavhrvxyfn4yqkji3tw5b3ea),
data: Uint8Array(14404) [
129, 89, 56, 64, 66, 58, 58, 0, 25, 8, 0, 16,
8, 8, 82, 90, 82, 25, 0, 8, 16, 58, 33, 25,
25, 25, 41, 33, 0, 8, 16, 8, 33, 99, 156, 165,
123, 181, 156, 140, 140, 107, 115, 123, 107, 123, 107, 107,
90, 66, 132, 123, 99, 165, 165, 165, 132, 99, 49, 123,
115, 90, 66, 0, 0, 25, 25, 25, 25, 33, 25, 8,
33, 25, 107, 123, 90, 99, 90, 115, 107, 16, 25, 82,
90, 173, 99, 58, 82, 49, 66, 99, 99, 90, 82, 99,
41, 115, 33, 41,
... 14304 more items
],
tileSize: { width: 120, height: 120 }
},
...
}{
'30': {
'480,0,514,60': CID(bafyreidslhcfyghycmpqtsvboms4623cinhtkqfctz64dvqyxw3ervo6t4),
'480,60,514,120': CID(bafyreihmweufxt2nq3axnujiurnsgkzkejzakwvkr56fgp6tsureujrzcm),
'480,120,514,180': CID(bafyreid7zfogsdrkl3ng22yqeny5aj7hhioph75kik7xjfxuyhvivaeave),
'480,180,514,240': CID(bafyreidjxno5kq7riwykklict4zu7kfk5b4wycvgxlhtkwgpkgoqsgwxhi),
'480,240,514,300': CID(bafyreigs3udscqv2mqvkmas3b6g2fy42dh3uy7orr4tvmhrfs6xneesfny),
'480,300,514,360': CID(bafyreighxzwr3sfyzjmkdppdhengkgdf2qxqx5nbefaqkm6kp7ghqajesi),
'480,360,514,420': CID(bafyreife3lpyz4vkvsmhlp6r46r72wkr3kxb5t4a3e3luhlzfw3rz3fbu4),
'480,420,514,480': CID(bafyreihyexbwogtgjhk6lwt5p577ls6hcoi53ggvjb24xnh7kfmsobnphe),
'480,480,514,515': CID(bafyreie6dflpabv3ywckcigfpkljlvvlruexpfjhzaiwv7lxz6gjqwk54q)
},
'60': {
'480,0,514,120': CID(bafyreibjdiqovqvopi4owtk36iyenqe7reykkfsromy3l4fsmc6iuydd7y),
'480,120,514,240': CID(bafyreih2jnnsgsvhjouhy5h3fpdmsahm5v545taljdgmbdruprzo2txbs4),
'480,240,514,360': CID(bafyreicfd6cmsjc6taxx7kgw3qaol7ourfbsh57qajs6bwt333b3q5pfoi),
'480,360,514,480': CID(bafyreiffelgsnbcl352drv7hdmlisjh3owlfut2cdmtvahcxlygdwxnvjy),
'480,480,514,515': CID(bafyreieupxskp4jnhrva6t3wohsqn4uzgfngti74sysu3jypdsgpkkzyma)
},
'120': {
'480,0,514,240': CID(bafyreiggzc74xwce3wn6je2bx5evpuun3gi7evjcbzwtkp3ck2hkzq4lmq),
'480,240,514,480': CID(bafyreiax5o26tyun3miuvv7zsyf47cmtihinplkxjrccuiemuwmztisy74),
'480,480,514,515': CID(bafyreib6xrt6daxw45t342miu7mk6yugso4f4sq25wtimdb4iv4omutf7e)
},
'240': {
'480,0,514,480': CID(bafyreigkdgkrgpnpnqcion3vaiq72dyedq2qdkvb2sulpln4tkhefkkfb4),
'480,480,514,515': CID(bafyreiahb7az6lnj63bfefogbp6w5vq5aczz3ouoh2aeen7zgbb2j5wzge)
},
'515': {
'0,0,514,515': CID(bafyreibwt4pakge4urf63bwn2ot2juolaaayval6wlwnokt4ztc2uyisbe)
}
}{
cid: 'bafyreigdmqpykrgxyaxtlafqpqhzrb7qy2rh75nldvfd4kok6gl47quzvy',
max_Dimensions: [
30, 60, 120,
240, 515
],
window: [ 0, 0, 514, 515 ],
bbox: [
-28493.166784412522,
4224973.143255847,
2358.211624949061,
4255884.5438021915
]
}interface IDocumentInfo {
geodidid: string;
documentVal: any;
parentid?: string;
}interface LoadInfo {
documentInfo: IDocumentInfo;
powergateInstance: Powergate
}interface IPinInfo {
geodidid: string;
cid: string;
pinDate: Date;
token: string
} yarn add -D @astralprotocol/core
OR
npm install -D @astralprotocol/core
import AstralClient from '@astralprotocol/core';
OR
const AstralClient = require('@astralprotocol/core');import AstralClient from '@astralprotocol/core';
async function run(){
// Create a new Astral Client Instance with the user's ethAddress
// and a subgraph endpoint (check the latest one @astralprotocol/subgraph)
let astral = new AstralClient(
'0xa3e1c2602f628112E591A18004bbD59BDC3cb512',
'https://api.thegraph.com/subgraphs/name/astralprotocol/spatialassetsv06'
);
try{
// Creates a Genesis GeoDID
const genDocRes = await astral.createGenesisGeoDID('collection')
console.log(genDocRes);
// With the returned IDocumentInfo from the last function, we can pin it.
// Since no token was specified the client will assign a new auth Token to the user.
const results = await astral.pinDocument(genDocRes);
console.log(results);
const token = results.token;
// With the Auth Token and the GeoDID ID we can load the document with the loadDocument function
const loadResults = await astral.loadDocument(results.geodidid, token);
console.log(loadResults);
console.log('\n');
console.log('\n');
// Creates a Child GeoDID Item of the priviously created Genesis GeoDID
const itemres = await astral.createChildGeoDID('item', results.geodidid, 'item1');
console.log(itemres)
console.log('\n');
// With the returned IDocumentInfo from the last function, we can pin it.
// This time we reuse the same token that was created earlier to pin the child document to the same instance.
const itemresults = await astral.pinDocument(itemres, token);
console.log(itemresults);
console.log('\n');
// With the Auth Token and the GeoDID ID we can load the document with the loadDocument function
const loadItemResults = await astral.loadDocument(itemresults.geodidid, token);
console.log(loadItemResults);
console.log('\n');
// Here we can display the string representation of the DID Document
console.log(JSON.stringify(loadItemResults.documentInfo.documentVal));
}catch(e){
console.log(e);
}
}node testScript.js[
'@context':'https://w3id.org/did/v1',
id:'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre',
publicKey: [
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre#controller',
type: 'Secp256k1VerificationKey2018',
controller: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre',
ethereumAddress: '0x4B11B9A1582E455c2C5368BEe0FF5d2F1dd4d28e'
}
],
did_metadata:{
type:'collection',
created:'2019-03-23T06:35:22Z',
updated:'2019-03-23T06:37:45Z'
},
links:[
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre',
type: 'collection',
rel: 'root'
},
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre',
type: 'collection',
rel: 'self'
}
],
service:[
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre#collection-metadata'
type: collection-metadata
serviceEndpoint: <CID or URL>
}
]
]yarn add @astralprotocol/core @astralprotocol/contracts dotenv bs58 truffle @truffle/hdwallet-providerconst HDWalletProvider = require("@truffle/hdwallet-provider");
require('dotenv').config();
// Create a .env file with your MNEMONIC and a ROPSTEN API key from INFURA
// Must have the following format:
// MNEMONIC="words here "
// ROPSTEN_API_KEY=https://ropsten.infura.io/v3/key
let mnemonic = process.env.MNEMONIC
let ropstenURL = process.env.ROPSTEN_API_KEY
let provider = new HDWalletProvider({
mnemonic: {
phrase: mnemonic,
},
providerOrUrl: ropstenURL,
});
module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 8545,
network_id: "*",
},
ropsten: {
provider: provider,
network_id: "3",
},
},
compilers: {
solc: {
version: "0.6.12",
},
},
};const { AstralClient } = require('@astralprotocol/core');
const SpatialAssets = require("@astralprotocol/contracts/build/contracts/SpatialAssets.json")
const bs58 = require('bs58')
module.exports = async function (callback) {
const stringToBytes = (string) => web3.utils.asciiToHex(string)
// based on https://ethereum.stackexchange.com/questions/17094/how-to-store-ipfs-hash-using-bytes32
// Return bytes32 hex string from base58 encoded ipfs hash,
// stripping leading 2 bytes from 34 byte IPFS hash
// Assume IPFS defaults: function:0x12=sha2, size:0x20=256 bits
// E.g. "QmNSUYVKDSvPUnRLKmuxk9diJ6yS96r1TrAXzjTiBcCLAL" -->
// "0x017dfd85d4f6cb4dcd715a88101f7b1f06cd1e009b2327a0809d01eb9c91f231"
function getBytes32FromIpfsHash(ipfsListing) {
return "0x"+bs58.decode(ipfsListing).slice(2).toString('hex')
}
try {
const accounts = await web3.eth.getAccounts()
const userAccount = accounts[0]
// find contract in network 3 (Ropsten)
const SpatialAssetsContract = new web3.eth.Contract(SpatialAssets.abi, SpatialAssets.networks['3'].address, {
from: userAccount,
data: SpatialAssets.deployedBytecode,
});
// update the endpoint to the latest
const subgraphEndpoint = "https://api.thegraph.com/subgraphs/name/astralprotocol/spatialassetsfinalv1"
const astral = await AstralClient.build(userAccount, subgraphEndpoint, "https://astralinstance.tk");
const storage = stringToBytes('FILECOIN');
// Creates a Genesis GeoDID
const genDocRes = await astral.createGenesisGeoDID('collection')
console.log(genDocRes);
// With the returned IDocumentInfo from the last function, we can pin it.
// Since no token was specified the client will assign a new auth Token to the user.
const results = await astral.pinDocument(genDocRes);
console.log(results);
// register the geodid id and cid obtained. Type 0 because it is a collection
console.log(results.geodidid)
console.log(results.cid)
const bytes32GeoDID= getBytes32FromIpfsHash(results.geodidid.substring(8));
const bytes32Cid = getBytes32FromIpfsHash(results.cid);
try {
await SpatialAssetsContract.methods.registerSpatialAsset(userAccount, bytes32GeoDID, stringToBytes(''),[], bytes32Cid, storage,0).send()
.on('receipt', function(receipt){
// receipt example
console.log(receipt);
})
.on('error', function(error) { // If the transaction was rejected by the network with a receipt, the second parameter will be the receipt.
console.log(error);
});
}
catch (err) {
// Will throw an error if tx reverts
console.log(err)
}
// With the Auth Token and the GeoDID ID we can load the document with the loadDocument function
const loadResults = await astral.loadDocument(results.geodidid);
console.log(loadResults);
}
catch(error) {
console.log(error)
}
callback()
};"deployGeoDIDs": "truffle exec scripts/deployGeoDIDs.js --network ropsten",yarn deployGeoDIDsenum FeatureType { Point, LineString, Polygon } // MultiPoint? MultiLineString? MultiPolygon?
struct Point {
FeatureType type, // set to FeatureType.Point
int[2] coordinates // [lon, lat]
}
struct LineString {
FeatureType type, // set to FeatureType.LineString
int[][2] coordinates // [[lon0, lat0],[lon1, lat1], ... ,[lonN, latN]]
}
struct Polygon {
FeatureType type, // set to FeatureType.Polygon
int[][][2] coordinates // [[lon0, lat0],[lon1, lat1], ... ,[lonN, latN]]
}
// not sure if my nested array syntax is right lolLineString s = LineString(FeatureType.LineString, [[0,0],[1,1],[1,2]])
function length (Feature inputFeature) public returns (int length) {
require(inputFeature.type == "LineString", "can only calculate the length of a linestring");
// Calculate the length
return length;
}
// lol forgive my horrendous pseudocodeconst Web3 = require('web3')
const ethSpatial = require('eth-spatial')
let web3 = new Web3(...);
let web3spatial = new ethSpatial(web3);[
{
'@context': 'https://w3id.org/did/v1',
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre',
publicKey: [
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre#controller',
type: 'Secp256k1VerificationKey2018',
controller: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre',
ethereumAddress: '0x4B11B9A1582E455c2C5368BEe0FF5d2F1dd4d28e'
}
],
didmetadata: { type: 'item', created: '2021-03-12T15:56:10.937Z' },
links: [
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre',
type: 'item',
rel: 'root'
},
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre',
type: 'item',
rel: 'self'
}
],
service: [
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre#item-metadata-1'
type: item-metadata
serviceEndpoint: <CID or URL>
},
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre#geojson-1'
type: geojson
serviceEndpoint: <CID or URL>
},
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre#geojson-2'
type: geojson
serviceEndpoint: <CID or URL>
},
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre#geotiff-1'
type: geotiff
serviceEndpoint: <CID or URL>
},
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre#json-1'
type: json
serviceEndpoint: <CID or URL>
},
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre#misc-1'
type: misc
serviceEndpoint: <CID or URL>
}
]
}
]https://api.thegraph.com/subgraphs/name/astralprotocol/spatialassetsfinalv1
wss://api.thegraph.com/subgraphs/name/astralprotocol/spatialassetsfinalv1yarn add @astralprotocol/subgraph{
geoDIDs {
id
owner
cid
storage
root
parent
edges {
id
childGeoDID {
id
}
}
active
type
}
}Planned upgrades to the GeoDID Method Specification

import { getImageFromUrl, startTile, getGeoTile } from "ipld-geotiff";
import { IPFS, create } from "ipfs";
async function example(){
const url = 'http://download.osgeo.org/geotiff/samples/gdal_eg/cea.tif';
// bbox that is sent from client
const request = [
-28493.166784412522,
4224973.143255847,
2358.211624949061,
4255884.5438021915
];
// First create instance of IPFS
const ipfs: IPFS = await create();
// Request TIFF from Endpoint
const image = await getImageFromUrl(url);
// Start the tiling and encoding process
const ires: IResponse = await startTile(ipfs, image);
// Use GetGeoTile to obtain the tile that you would like
const tiff_of_tile = await getGeoTile(ipfs, ires.cid, ires.max_Dimensions);
}constructor(string memory uri) public



function registerRole() publicfunction enableStorage(bytes32 offChainStorage) publicfunction disableStorage(bytes32 offChainStorage) publicfunction registerSpatialAsset (
address owner,
bytes32 geoDIDId,
bytes32 parentGeoDIDId ,
bytes32[] memory childrenGeoDIDIds,
bytes32 cid,
bytes32 offChainStorage,
uint256 geoDIDtype
) publicfunction addChildrenGeoDIDs(
bytes32 geoDIDId,
bytes32[] memory childrenGeoDIDIds
) publicfunction addParentGeoDID(
bytes32 geoDIDId,
bytes32 parentGeoDIDId
) publicfunction removeChildrenGeoDIDs(
bytes32 geoDIDId,
bytes32[] memory childrenGeoDIDIds
) publicfunction removeParentGeoDID(
bytes32 geoDIDId,
bytes32 parentGeoDIDId
) publicfunction deactivateSpatialAsset(
bytes32 geoDIDId,
bytes32[] memory childrenToRemove
) publicyarn add @astralprotocol/contractsgit clone git@github.com:AstralProtocol/astralprotocol.git
cd astralprotocol/packages/contractsMNEMONIC="mnemonic phrase goes here with testnet ether in address[0] on ropsten cool"
ROPSTEN_API_KEY=https://ropsten.infura.io/v3/<PROJECT ID HERE>
// bbox that is sent from client
const request = [
-28493.166784412522,
4224973.143255847,
2358.211624949061,
4255884.5438021915
];
// convert to window to round to nearest tile size
const targetWindow: ImageMetadata = await GeoUtils.bboxtoWindow(max_window, max_bbox, request);
// Use GetGeoTile to obtain the tile that you would like
const tiff_of_tile = await getGeoTile(ipfs, cid, ires.max_Dimensions);[
'0,0,240,240',
'0,0,240,240/cid',
'0,0,240,240/data',
'0,0,240,240/window',
'0,0,240,240/window/0',
'0,0,240,240/window/1',
'0,0,240,240/window/2',
'0,0,240,240/window/3',
'0,0,240,240/tileSize',
'0,0,240,240/tileSize/width',
'0,0,240,240/tileSize/height',
...
...
'240,240,480,480',
'240,240,480,480/cid',
'240,240,480,480/data',
'240,240,480,480/window',
'240,240,480,480/window/0',
'240,240,480,480/window/1',
'240,240,480,480/window/2',
'240,240,480,480/window/3',
'240,240,480,480/tileSize',
'240,240,480,480/tileSize/width',
'240,240,480,480/tileSize/height',
'480,240,514,480',
'480,240,514,480/cid',
'480,240,514,480/data',
'480,240,514,480/window',
'480,240,514,480/window/0',
'480,240,514,480/window/1',
'480,240,514,480/window/2',
'480,240,514,480/window/3',
'480,240,514,480/tileSize',
'480,240,514,480/tileSize/width',
'480,240,514,480/tileSize/height'
]<Buffer 81 59 e1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... 57554 more bytes>[
<Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... 57550 more bytes>
]ArrayBuffer {
[Uint8Contents]: <4d 4d 00 2a 00 00 00 08 00 18 01 00 00 03 00 00 00 01 00 f0 00 00 01 01 00 03 00 00 00 01 00 f0 00 00 01 02 00 03 00 00 00 01 00 08 00 00 01 03 00 03 00 00 00 01 00 01 00 00 01 06 00 03 00 00 00 01 00 01 00 00 01 11 00 04 00 00 00 01 00 00 03 e8 01 15 00 03 00 00 00 01 00 01 00 00 01 16 00 04 00 00 ... 58500 more bytes>,
byteLength: 58600
}The Core Specification of the GeoDID; includes default fields for specification.
[
{
'@context': 'https://w3id.org/did/v1',
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre',
publicKey: [
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre#controller',
type: 'Secp256k1VerificationKey2018',
controller: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre',
ethereumAddress: '0x4B11B9A1582E455c2C5368BEe0FF5d2F1dd4d28e'
}
],
didmetadata: { type: 'collection', created: '2021-03-12T15:56:10.937Z' },
links: [
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre',
type: 'collection',
rel: 'root'
},
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre',
type: 'collection',
rel: 'self'
}
],
service: [
{
id: 'did:geo:QmdDEcQbiFEY5YWvKgk2exd6XLetgfVmswZvXRgNkpehre#' + `${<ServiceType>}` + `${index}`
type: <ServiceType>
serviceEndpoint: <CID or URL>
}
]
}
]



