UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

3 lines (2 loc) 16.2 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */ import{__decorate as e}from"tslib";import t from"../../core/Accessor.js";import i from"../../core/Error.js";import n from"../../core/Logger.js";import{getOrCreateMapValue as o}from"../../core/MapUtils.js";import{createAbortError as s}from"../../core/promiseUtils.js";import{parseWhereClause as a}from"../../core/sql.js";import{property as r,subclass as p}from"../../core/accessorSupport/decorators.js";import d from"../../geometry/Extent.js";import m from"../../geometry/Polygon.js";import{initializeProjection as l,project as h}from"../../geometry/projectionUtils.js";import{wgs84 as c}from"../../geometry/support/spatialReferenceUtils.js";import{systemOidFieldName as y,systemOriginIdFieldName as u,systemDestinationIdFieldName as f,systemIsSpatialFieldName as g,systemLayoutGeometryFieldName as b}from"./constants.js";import{recursiveParseSqlToCypher as T}from"./cypherUtils.js";import w from"./SessionMemoryStorage.js";import{utilsExtentToInBoundsRings as I}from"./supportUtils.js";import{executeQueryStreaming as M}from"../../rest/knowledgeGraphService.js";import D from"../../rest/knowledgeGraph/GraphQueryStreaming.js";import E from"../../rest/support/Query.js";let N=class extends t{constructor(e){super(e),this._processingCacheUpdatesLookup=new Map,this.knowledgeGraph=null,this.inclusionModeDefinition={generateAllSublayers:!0,namedTypeDefinitions:new Map},this.entityTypeNames=new Set,this.relationshipTypeNames=new Set,this.geographicLookup=new Map,this.sublayerCaches=new Map,this.nodeConnectionsLookup=new Map,this.relationshipConnectionsLookup=new Map,this.memberIdTypeLookup=new Map;const t=new Map;e.knowledgeGraph.dataModel.entityTypes?.forEach(i=>{i.name&&(t.set(i.name,"entity"),this._processingCacheUpdatesLookup.set(i.name,[]),e.inclusionModeDefinition&&!e.inclusionModeDefinition?.generateAllSublayers||this.entityTypeNames.add(i.name),i.properties?.forEach(e=>{e.geometryType&&"esriGeometryNull"!==e.geometryType&&this.geographicLookup.set(i.name,{name:e.name??"",geometryType:e.geometryType})}))}),e.knowledgeGraph.dataModel.relationshipTypes?.forEach(i=>{i.name&&(t.set(i.name,"relationship"),this._processingCacheUpdatesLookup.set(i.name,[]),e.inclusionModeDefinition&&!e.inclusionModeDefinition?.generateAllSublayers||this.relationshipTypeNames.add(i.name),i.properties?.forEach(e=>{e.geometryType&&"esriGeometryNull"!==e.geometryType&&this.geographicLookup.set(i.name,{name:e.name??"",geometryType:e.geometryType})}))}),e.inclusionModeDefinition?.namedTypeDefinitions.forEach((i,s)=>{if("entity"===t.get(s))this.entityTypeNames.add(s);else{if("relationship"!==t.get(s))return n.getLogger(this).warn(`A named type, ${s}, was in the inclusion list that wasn't in the data model and will be removed`),void e.inclusionModeDefinition?.namedTypeDefinitions.delete(s);this.relationshipTypeNames.add(s)}const a=new Map;i.members?.forEach(e=>{o(this.memberIdTypeLookup,e.id,()=>new Set).add(s)}),this.sublayerCaches.set(s,a)})}addToLayer(e){e.forEach(({typeName:e,id:t})=>{if(!this.inclusionModeDefinition)throw new i("knowledge-graph:layer-data-manager","You cannot add to a layer's exclusion list if it was not created with an exclusion list originally");if(this.inclusionModeDefinition.namedTypeDefinitions.has(e)){if(this.inclusionModeDefinition.namedTypeDefinitions.has(e)){const i=this.inclusionModeDefinition.namedTypeDefinitions.get(e);i.members||(i.members=new Map),i.members.set(t,{id:t}),o(this.memberIdTypeLookup,t,()=>new Set).add(e)}}else{const i=new Map;i.set(t,{id:t}),this.inclusionModeDefinition.namedTypeDefinitions.set(e,{useAllData:!1,members:i}),o(this.memberIdTypeLookup,t,()=>new Set).add(e)}})}getById(e){return w.getInstance().readFromStoreById(e)}async getData(e,t,i){if(t.objectType.name&&this.inclusionModeDefinition?.namedTypeDefinitions&&this.inclusionModeDefinition.namedTypeDefinitions.size>0&&!this.inclusionModeDefinition.namedTypeDefinitions.has(t.objectType.name))return[];let n;if(n=e||new E({where:"1=1",outFields:["*"]}),"link-chart"===t.parentCompositeLayer.type){const e=t.parentCompositeLayer,i=this._processingCacheUpdatesLookup.get(t.objectType.name??""),o=n.outFields;o&&1===o.length&&o[0]===y&&"1=1"===n.where||await Promise.all(i??[]);const s=this.sublayerCaches.has(t.objectType.name??"")?Array.from(this.sublayerCaches.get(t.objectType.name)?.values()):[],a=[];return s.forEach(i=>{if(this.relationshipTypeNames.has(t.objectType.name)){i.geometry=e.relationshipLinkChartDiagramLookup.get(i.attributes[t.objectIdField]);const n=this.memberIdTypeLookup.get(i.attributes[u]),o=this.memberIdTypeLookup.get(i.attributes[f]),s=this._isEndEntitySpatial(n,i,u),a=this._isEndEntitySpatial(o,i,f);i.attributes[g]=Number(s&&a)}else{i.geometry=e.entityLinkChartDiagramLookup.get(i.attributes[t.objectIdField]);const n=this.geographicLookup.get(t.objectType.name);n&&i.attributes[n.name]?i.attributes[g]=1:i.attributes[g]=0}i.attributes[b]=i.geometry,a.push(i)}),a}return this.retrieveDataFromService(n,t,i)}async getConnectedRecordIds(e,t,i){const n=[];let o="";const s=this._getNamedTypeIdMapFromNodeIds(e);if(t&&0!==t?.length){for(const e of t)o=o+e+"|";o=o.slice(0,-1)}const a={},r=[];for(const[m,l]of s){const e=`${m}_ids`;a[e]=l,t&&0!==t?.length?r.push(`MATCH (n:${m}) WHERE id(n) IN $${e} WITH n MATCH (n)-[r:${o}]-(m) RETURN id(r), type(r), id(m), labels(m)[0]`):r.push(`MATCH (n:${m}) WHERE id(n) IN $${e} WITH n MATCH (n)-[r]-(m) RETURN id(r), type(r), id(m), labels(m)[0]`)}if(!r.length)return n;const p=r.join(" UNION "),d=(await M(this.knowledgeGraph,new D({openCypherQuery:p,bindParameters:a}),{signal:i?.signal})).resultRowsStream.getReader();for(;;){const{done:e,value:t}=await d.read();if(e)break;for(let i=0;i<t.length;i++){const e=t[i];n.push({id:e[0],typeName:e[1]}),n.push({id:e[2],typeName:e[3]})}}return n}async getRelationshipsBetweenNodes(e,t,i){const n=this._getNamedTypeIdMapFromNodeIds(e);if(0===n.size)return[];const o={relationshipExclusionIds:t,possibleConnectionEntityIds:e},s=[];for(const[d,m]of n.entries()){const e=`${d}_ids`;o[e]=m,s.push(`MATCH (n:${d}) WHERE id(n) IN $${e} WITH n MATCH (n)-[r]->(m) WHERE id(m) IN $possibleConnectionEntityIds AND NOT id(r) IN $relationshipExclusionIds RETURN id(r), type(r)`)}const a=s.join(" UNION "),r=[],p=(await M(this.knowledgeGraph,new D({openCypherQuery:a,bindParameters:o}),{signal:i?.signal})).resultRowsStream.getReader();for(;;){const{done:e,value:t}=await p.read();if(e)break;for(let i=0;i<t.length;i++){const e=t[i];r.push({id:e[0],typeName:e[1]})}}return r}async getRelationshipsFromNodes(e,t,i,n){const o=this._getNamedTypeIdMapFromNodeIds(e);if(0===o.size||0===t.length)return[];const s={relationshipExclusionIds:i,possibleConnectionEntityIds:t},a=[];for(const[l,h]of o.entries()){const e=`${l}_ids`;s[e]=h,a.push(`MATCH (n:${l}) WHERE id(n) IN $${e} WITH n MATCH (n)-[r]-(m) WHERE id(m) IN $possibleConnectionEntityIds AND NOT id(r) IN $relationshipExclusionIds RETURN id(r), type(r)`)}const r=a.join(" UNION "),p=new Map,d=(await M(this.knowledgeGraph,new D({openCypherQuery:r,bindParameters:s}),{signal:n?.signal})).resultRowsStream.getReader();for(;;){const{done:e,value:t}=await d.read();if(e)break;for(let i=0;i<t.length;i++){const e=t[i];let n=p.get(e[1]);n||(n=new Set,p.set(e[1],n)),n.add(e[0])}}const m=[];for(const[l,h]of p)for(const e of h)m.push({id:e,typeName:l});return m}async refreshCacheContent(e,t,n,a=!0,r){const p=w.getInstance(),d=[],m=new Map,l=new Map;this.knowledgeGraph.dataModel.entityTypes?.forEach(e=>{e.name&&l.set(e.name,e)}),this.knowledgeGraph.dataModel.relationshipTypes?.forEach(e=>{e.name&&l.set(e.name,e)}),e||this.inclusionModeDefinition?e?e.forEach(e=>{if(this.memberIdTypeLookup.has(e))for(const t of this.memberIdTypeLookup.get(e))m.has(t)?m.get(t)?.push(e):m.set(t,[e])}):this.inclusionModeDefinition?.namedTypeDefinitions?.forEach((e,t)=>{e.useAllData?m.set(t,null):e.members&&e.members.forEach(e=>{m.has(t)&&null!==m.get(t)?m.get(t)?.push(e.id):m.set(t,[e.id])})}):(this.knowledgeGraph.dataModel.entityTypes?.forEach(e=>{e.name&&m.set(e.name,null)}),this.knowledgeGraph.dataModel.entityTypes?.forEach(e=>{e.name&&m.set(e.name,null)}));for(const[s,h]of m){const e=new Set(h),m=new Promise((d,m)=>{const c=async()=>{const d=new Set,m=[];let c,u="",f=!1;if(t||l.get(s)?.properties?.forEach(e=>{e.name&&d.add(e.name)}),n&&this.geographicLookup.has(s)){const e=this.geographicLookup.get(s)?.name;e&&d.add(e)}if(this.entityTypeNames.has(s))u=`MATCH (n:${s}) ${h?"WHERE id(n) IN $ids ":""}return ID(n)`,d.forEach(e=>{u+=`, n.${e}`,m.push(e)});else{if(!this.relationshipTypeNames.has(s))throw new i("knowledge-graph:layer-data-manager",`The graph type of ${s} could not be determined. Was this type set in the KG data model and inclusion definition?`);f=!0,u=`MATCH ()-[n:${s}]->() ${h?"WHERE id(n) IN $ids ":""}return ID(n), id(startNode(n)), id(endNode(n))`,d.forEach(e=>{u+=`, n.${e}`,m.push(e)})}c=new D(h?{openCypherQuery:u,bindParameters:{ids:h}}:{openCypherQuery:u});const g=(await M(this.knowledgeGraph,c,{signal:r?.signal})).resultRowsStream.getReader();for(;;){const{done:t,value:i}=await g.read();if(t)break;const n=[];for(let s=0;s<i.length;s++){const t=i[s];let a=0,r=0;const p={properties:{}};for(p.id=t[a],a++,r++,f&&(p.originId=t[a],a++,r++,p.destinationId=t[a],a++,r++,o(this.nodeConnectionsLookup,p.originId,()=>new Set).add(p.id),o(this.nodeConnectionsLookup,p.destinationId,()=>new Set).add(p.id),o(this.relationshipConnectionsLookup,p.id,()=>[p.originId,p.destinationId]));a<t.length;a++)p.properties[m[a-r]]=t[a];e.delete(p.id),n.push(p)}const r=p.writeToStore(n,y,this.geographicLookup.get(s)?.name);this.sublayerCaches.has(s)||this.sublayerCaches.set(s,new Map),a&&!this.inclusionModeDefinition?.namedTypeDefinitions.has(s)&&this.inclusionModeDefinition?.namedTypeDefinitions.set(s,{useAllData:!1,members:new Map}),a&&!this.inclusionModeDefinition?.namedTypeDefinitions.get(s).members&&(this.inclusionModeDefinition.namedTypeDefinitions.get(s).members=new Map);const d=this.sublayerCaches.get(s);r.forEach(e=>{d?.set(e.attributes[y],e),a&&!this.inclusionModeDefinition?.namedTypeDefinitions.get(s).members.has(e.attributes[y])&&(this.inclusionModeDefinition?.namedTypeDefinitions.get(s).members.set(e.attributes[y],{id:e.attributes[y]}),o(this.memberIdTypeLookup,e.attributes[y],()=>new Set).add(s))})}const b=this.inclusionModeDefinition?.namedTypeDefinitions.get(s);if(b)for(const t of e)b.members?.delete(t)};c().then(()=>{d(null)}).catch(e=>{"AbortError"===e.name?d(null):m(e)})});d.push(m),this._processingCacheUpdatesLookup.get(s)?.push(m)}if(await Promise.all(d),r?.signal?.aborted)throw s()}removeFromLayer(e){const t=new Set,i=new Set(e.map(e=>e.id));for(const n of e)t.add(n.typeName),1===this.memberIdTypeLookup.get(n.id)?.size?this.memberIdTypeLookup.delete(n.id):this.memberIdTypeLookup.get(n.id)?.delete(n.typeName),this.inclusionModeDefinition?.namedTypeDefinitions.forEach((e,t)=>{t===n.typeName&&e.members?.has(n.id)&&e.members.delete(n.id)});t.forEach(e=>{this.sublayerCaches.get(e)?.forEach((t,n)=>{i.has(n)&&this.sublayerCaches.get(e)?.delete(n)})})}async retrieveDataFromService(e,t,n){const o=w.getInstance(),s=new Set,r=[];let p,u="",f=[];const g="relationship"===t.graphType,b=this.inclusionModeDefinition?.namedTypeDefinitions?.get(t.objectType.name)?.useAllData,E=t.parentCompositeLayer.sublayerIdsCache.get(t.objectType.name);let N=!b&&E?Array.from(E).sort():null;if(this.inclusionModeDefinition?.namedTypeDefinitions?.get(t.objectType.name)?.useAllData)this.inclusionModeDefinition?.namedTypeDefinitions?.get(t.objectType.name)?.useAllData&&null!=e.objectIds&&(N=e.objectIds);else if(null!=e.objectIds&&N&&N.length>0){const t=e.objectIds;e.objectIds=N.filter(e=>t.includes(e))}else if(null!=e.objectIds)N=e.objectIds;else{if(this.inclusionModeDefinition?.namedTypeDefinitions.has(t.objectType.name)&&(!this.inclusionModeDefinition.namedTypeDefinitions.get(t.objectType.name)?.members||this.inclusionModeDefinition.namedTypeDefinitions.get(t.objectType.name)?.members?.size<1))return e.objectIds=[],[];e.objectIds=N}if(null!=e.outFields){const i=e.outFields;i.includes("*")?t.fields.forEach(e=>{s.add(e.name)}):i.forEach(e=>{e!==y&&e!==t.geometryFieldName&&s.add(e)})}if(null!=e.geometry){const n=e.geometry;let o;const y=t.parentCompositeLayer.dataManager.knowledgeGraph.serviceDefinition,f=y?.spatialReference,b=y?.serviceCapabilities?.geometryCapabilities;let T=b?.geometryMaxBoundingRectangleSizeX,w=b?.geometryMaxBoundingRectangleSizeY;if("point"===n.type){let e=n;e.spatialReference?.isWGS84||(await l(e.spatialReference,c),e=h(e,c)),o=new d({spatialReference:c,xmin:e.x-1e-4,ymin:e.y-1e-4,xmax:e.x+1e-4,ymax:e.y+1e-4})}else n?.extent?.spatialReference&&!n.spatialReference?.isWGS84?(await l(n.extent.spatialReference,c),o=h(n.extent,c)):o=n.extent;if(T&&w&&f){if(4326!==f.wkid){const e=new d({spatialReference:f,xmax:T,ymax:w}),t=h(e,c);T=t.xmax,w=t.ymax}if(o.xmax-o.xmin>T)throw new i("knowledge-graph:layer-data-manager",`Extent x bounds should be within ${T}° latitude, limit exceeded`);if(o.ymax-o.ymin>w)throw new i("knowledge-graph:layer-data-manager",`Extent y bounds should be within ${w}° longitude, limit exceeded`)}if(null!=e.where&&"1=1"!==e.where){const i=await a(e.where.toUpperCase(),t.fieldsIndex);t.fields.forEach(e=>{i.fieldNames.includes(e.name)&&s.add(e.name)})}u=g?`Match ()-[n:${t.objectType.name}]->() WHERE esri.graph.ST_Intersects($param_filter_geom, n.${t.geometryFieldName}) return ID(n), id(startNode(r)), id(endNode(r))`:`Match (n:${t.objectType.name}) WHERE esri.graph.ST_Intersects($param_filter_geom, n.${t.geometryFieldName}) return ID(n)`,t.geometryFieldName&&s.add(t.geometryFieldName),s.forEach(e=>{u+=`, n.${e}`,r.push(e)}),p=new D({openCypherQuery:u,bindParameters:{param_filter_geom:new m({rings:I(o)})}})}else{let i="";if(null!=e.where&&"1=1"!==e.where){const n=await a(e.where,t.fieldsIndex);t.fields.forEach(e=>{n.fieldNames.includes(e.name)&&s.add(e.name)});const o={systemOidFieldName:y,supportedSqlTypes:new Set(["column-reference","string","number","binary-expression"]),supportedSqlOperators:new Set(["=","<","<=","<>",">",">=","AND","OR","LIKE"]),unsupportedOperationFound:!1};i=T(n.parseTree,o),o.unsupportedOperationFound&&(i="")}let n="";n=g?`Match ()-[n:${t.objectType.name}]->()`:`Match (n:${t.objectType.name})`;let o=!1;N&&(o=!0,n+=" WHERE ID(n) IN $ids"),i&&(n+=o?" AND":" WHERE",n+=` ${i}`),n+=" return ID(n)",g&&(n+=", id(startNode(n)), id(endNode(n))"),e.returnGeometry&&t.geometryFieldName&&s.add(t.geometryFieldName),s.forEach(e=>{n+=`, n.${e}`,r.push(e)}),p=new D(N?{openCypherQuery:n,bindParameters:{ids:N}}:{openCypherQuery:n})}const k=(await M(t.parentCompositeLayer.dataManager.knowledgeGraph,p,n)).resultRowsStream.getReader();for(;;){const{done:e,value:i}=await k.read();if(e)break;const n=[];for(let t=0;t<i.length;t++){const e=i[t];let o=0,s=0;const a={properties:{}};for(a.id=e[o],o++,s++,g&&(a.originId=e[o],o++,s++,a.destinationId=e[o],o++,s++);o<e.length;o++)a.properties[r[o-s]]=e[o];n.push(a)}f=f.concat(o.writeToStore(n,y,t.parentCompositeLayer.dataManager.geographicLookup.get(t.objectType.name)?.name))}return f}_isEndEntitySpatial(e,t,i){for(const n of e??[])if(this.entityTypeNames.has(n)){const e=this.geographicLookup.get(n),o=e&&this.sublayerCaches.get(n)?.get(t.attributes[i]);if(e&&o?.attributes[e.name])return!0}return!1}_getNamedTypeIdMapFromNodeIds(e){const t=new Map;return e.forEach(e=>{if(this.memberIdTypeLookup.has(e))for(const i of this.memberIdTypeLookup.get(e)){if(!this.entityTypeNames.has(i))return;t.has(i)?t.get(i)?.push(e):t.set(i,[e])}}),t}};e([r()],N.prototype,"knowledgeGraph",void 0),e([r()],N.prototype,"inclusionModeDefinition",void 0),e([r()],N.prototype,"entityTypeNames",void 0),e([r()],N.prototype,"relationshipTypeNames",void 0),e([r()],N.prototype,"geographicLookup",void 0),e([r()],N.prototype,"sublayerCaches",void 0),e([r()],N.prototype,"nodeConnectionsLookup",void 0),e([r()],N.prototype,"relationshipConnectionsLookup",void 0),e([r()],N.prototype,"memberIdTypeLookup",void 0),N=e([p("esri.layers.knowledgeGraph.KnowledgeGraphLayerDataManager")],N);export{N as KnowledgeGraphLayerDataManager};