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

esri loader Angular example #75

Closed
banchana opened this issue Jan 12, 2018 · 16 comments

Comments

@banchana
Copy link

commented Jan 12, 2018

Has anyone worked with esri-loader and have implemented successfully?

I am looking at the cli example (https://github.com/tomwayson/esri-angular-cli-example) listed on the esri-loader site (https://github.com/Esri/esri-loader) and it is still using the old libraries.

Is there a lot of difference in terms of how it is implemented in various files shown here in this link https://gist.github.com/tomwayson/e6260adfd56c2529313936528b8adacd?

Thanks!

@tomwayson

This comment has been minimized.

Copy link
Member

commented Jan 12, 2018

@banchana

Here is a recent commit that migrates an angular repo from using angular-esri-loader to esri-loader:

jccartwright/autogrid@3b4fcaf

@tomwayson tomwayson changed the title esri loader example esri loader Angular example Jan 12, 2018

@tomwayson tomwayson added the question label Jan 12, 2018

@andygup

This comment has been minimized.

Copy link
Member

commented Jan 12, 2018

@banchana here's a component that may help you out. It was last tested with esri-loader v1.5 + angular/cli: 1.5.0 + angular 5.0.1 . I'm looking at creating an updated repo, it's a work in progress.


import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';

import { loadModules } from 'esri-loader';

@Component({
  selector: 'app-esri-map',
  templateUrl: './esri-map.component.html',
  styleUrls: ['./esri-map.component.css']
})


export class EsriMapComponent implements OnInit {

  // for JSAPI 4.x you can use the "any for TS types
  public mapView: any;
  // public dojoConfig: any;

  // this is needed to be able to create the MapView at the DOM element in this component
  @ViewChild('mapViewNode') private mapViewEl: ElementRef;

  constructor() { }

  public ngOnInit() {

    return loadModules([
      'esri/Map',
      'esri/views/MapView'
    ]).then(([Map, MapView]) => {
      const mapProperties: any = {
        basemap: 'hybrid'
      };

      const map: any = new Map(mapProperties);

      const mapViewProperties: any = {
        // create the map view at the DOM element in this component
        container: this.mapViewEl.nativeElement,
        // supply additional options
        center: [-12.287, -37.114],
        zoom: 12,
        map // property shorthand for object literal
      };

      this.mapView = new MapView(mapViewProperties);
    })
      .catch(err => {
        console.log(err);
      });
  } 
}


@banchana

This comment has been minimized.

Copy link
Author

commented Jan 12, 2018

Thank you Tom and Andy for your prompt response to my issue. I will work towards implementing this and will provide my feedback to you once I am done. Appreciate your efforts.

@jwasilgeo

This comment has been minimized.

Copy link
Member

commented Jan 12, 2018

@tomwayson

This comment has been minimized.

Copy link
Member

commented Jan 12, 2018

So @andygup

I see you're using any types in there. Are these instructions no longer valid?

https://github.com/Esri/esri-loader#4x-types

@banchana

This comment has been minimized.

Copy link
Author

commented Jan 12, 2018

Hey esri-loader team,
i have implemented the new stuff successfully.
I know your repo is still in progress, but I just wanted to let you know about one file that is still referencing the old angular-esri-loader, that was in esri-map.component.ts file. I updated that with what I thought should look like and was able to get my map working.
Thanks Much!
Banchana

@andygup

This comment has been minimized.

Copy link
Member

commented Jan 12, 2018

@tomwayson good catch, yes the best practice is to continue to use the __esri.XYZ pattern. For reference, in case others aren't sure what this means, you can grab the ArcGIS JS API type definitions via: https://github.com/Esri/jsapi-resources/tree/master/4.x/typescript

@tomwayson

This comment has been minimized.

Copy link
Member

commented Jan 12, 2018

@banchana I'm going to close this issue since you seem to have it working, feel free to reopen if needed.

@tomwayson tomwayson closed this Jan 12, 2018

@Huwei1158

This comment has been minimized.

Copy link

commented Apr 11, 2018

Are there more advanced operations for both the angular and arcgis apis?Such as spatial query, and attribute query.I want to turn the arcgis API into a service, and then import the service in other components to get the classes in the service, such as app.map = map;App. Color = Color.I'm in other components, I just need to get this app, and I can, without using the loadModules function over and over again.

@jwasilgeo

This comment has been minimized.

Copy link
Member

commented Apr 11, 2018

@Huwei1158 please see the 2018 Esri Dev Summit presentation slides that discuss some of the topics you're asking about: https://github.com/Esri/jsapi-resources/tree/master/frameworks/angular#presentations

@tomwayson

This comment has been minimized.

Copy link
Member

commented Apr 11, 2018

@Huwei1158 esri-loader definitely complicates interaction w/ the ArcGIS API for JavaScript in that you do need to wrap any functions that use 'esri' modules in a call to loadModules(). This means that something that might have previously been synchronous like creating a new Extent() from JSON now becomes asynchronous b/c it has to be wrapped in a promise. For this reason, esri-loader works best when your app makes limited use of the ArcGIS API. You are following best practices by isolating all interaction w/ the ArcGIS API into a service, but I don't know of a better approach than for that service to expose async functions like newMap(elementId, options), newColor(colorJSON), etc.

@Huwei1158

This comment has been minimized.

Copy link

commented Apr 12, 2018

@jwasilgeo Thank you. My level is limited, we are using arcgis api@3.18, and I want to turn it into the following:

import { Injectable } from '@angular/core';
import { loadScript, loadModules } from 'esri-loader'
@Injectable()
export class EsriService {
	map:any;
	config:any;
  constructor() { 
	var options = {
			url: 'http://218.241.213.230:8888/arcgis_js_api/library/3.18/3.18/init.js',
		};
		loadScript(options);
		loadModules(['esri/map','esri/config'],options).then(([Map,Config])=>{
//			this.map = Map;				
//			this.config = Config;
				this.map = function(a,b){
				return a*b
				} 
		});
//		this.map = function(a,b){
//		return a*b
//		}
  }
  

}

How do you break this callback function, get the Map in like this.map, output it, and then use it in the component.

@tomwayson

This comment has been minimized.

Copy link
Member

commented Apr 12, 2018

import { Injectable } from '@angular/core';
import { loadScript, loadModules } from 'esri-loader'

var options = {
  url: 'http://218.241.213.230:8888/arcgis_js_api/library/3.18/3.18/init.js',
};

@Injectable()
export class EsriService {

  esriConfig() {
		return loadModules(['esri/config'], options).then(([esriConfig]) => {
			return esriConfig;
		});
  },

  newMap(elementId, mapOptions) {
    return loadModules(['esri/map'], options).then(([Map]) => {
      return new Map(elementId, mapOptions);
    });
	}
}

Then in your component you might do something like:

mapService.esriConfig().then(esriConfig => {
	// TODO: do something w/ esriConfig here as needed, such as:
	esriConfig.defaults.io.corsEnabledServers.push('myserver');
	mapService.newMap('mapDiv',  { displayGraphicsOnPan:false }).then(map => {
		// TODO: do something w/ your map instance, like:
		map.on('extent-change', (delta, nexExtent) => {
			console.log(newExtent);
		});
	});
});
@Huwei1158

This comment has been minimized.

Copy link

commented Apr 12, 2018

Thank you. This is not what I want. Two returns are too much trouble.Every module has to be written.I used to combine with webpack and use promise to get the module directly.But I won't with angular.Here's what I did with webpack:
1.this is map.js

import esriLoader from 'esri-loader';
import arcgis_url from 'Conf/arcgisUrl';

var app = {};

/*

初始化地图,id为需要绑定的map id
*/
app.initMap = function(id){
var that = this;
var p = new Promise(function(resolve, reject){
esriLoader.loadModules(['dojo/parser', 'esri/config', 'esri/map', 'esri/layers/ArcGISDynamicMapServiceLayer','esri/layers/FeatureLayer',
"esri/toolbars/MeasureTools", "dojo/_base/array", "esri/layers/LayerDrawingOptions", "dojo/on", "dojo/query",
"esri/tasks/query", "esri/tasks/QueryTask", "esri/layers/GraphicsLayer", "esri/tasks/FindTask","esri/tasks/FindParameters", 'esri/tasks/BufferParameters', 'esri/SpatialReference', "esri/geometry/Extent",
'esri/toolbars/navigation', 'esri/toolbars/draw', 'esri/tasks/GeometryService', 'esri/symbols/Font',
'esri/symbols/SimpleMarkerSymbol', 'esri/symbols/SimpleFillSymbol', 'esri/symbols/SimpleLineSymbol',
'esri/symbols/TextSymbol', 'esri/Color', 'esri/graphic', 'esri/tasks/LengthsParameters', 'esri/geometry/Point',
'esri/geometry/Polyline', 'esri/tasks/AreasAndLengthsParameters', 'dojo/dom-attr', 'esri/geometry/normalizeUtils', 'dojo/domReady!'], arcgis_url.initUrl)
.then(([parser, esriConfig, Map, ArcGISDynamicMapServiceLayer, FeatureLayer, deMeasureTools, arrayUtils, LayerDrawingOptions, on, query,
Query, QueryTask, GraphicsLayer,FindTask,FindParameters,BufferParameters, SpatialReference, Extent,
Navigation, Draw, GeometryService, Font, SimpleMarkerSymbol, SimpleFillSymbol, SimpleLineSymbol,
TextSymbol, Color, Graphic, LengthsParameters, Point, Polyline, AreasAndLengthsParameters, domAttr, normalizeUtils]) => {
console.log(arcgis_url);

parser.parse();
esriConfig.defaults.io.corsEnabledServers.push("218.241.213.230:6080");
esriConfig.defaults.io.corsEnabledServers.push("sampleserver1.arcgisonline.com");
esriConfig.defaults.geometryService = new GeometryService(arcgis_url.GeometryService);
 esriConfig.defaults.io.proxyUrl = "http://218.241.213.230:8888/Java/proxy.jsp";
	esriConfig.defaults.io.alwaysUseProxy = false;
// create map with the given options at a DOM node w/ id 'mapNode'
/*extent:new Extent(121,29,122,29.5, new SpatialReference({ wkid:4610 }))*/
that.map = new Map(id, {
	  	center: [121.4, 29.3],
 	zoom: 11,
 	logo:false,
});

//设置地图坐标系类型  
 var spatialReference = new SpatialReference(4610);  
 that.map.spatialReference = spatialReference;  
var basemap = new ArcGISDynamicMapServiceLayer(arcgis_url.basemap);
basemap.id = "basemap";
 that.map.addLayer(basemap);
 //自己封装的测量工具,在服务器arcgisapi中
 var measurTool = new deMeasureTools({
     map: that.map
 }, "map-tool");
 /*that.map.onClick = function(e){
 	var t = e;
 	console.log(e);
 };*/
 
 var fieldsSelectionSymbol =new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID,
 new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,
new Color([255, 0, 0]), 2), new Color([255, 255, 0, 0.5]));
that.Map = Map;
that.ArcGISDynamicMapServiceLayer=ArcGISDynamicMapServiceLayer;
that.FeatureLayer=FeatureLayer;
that.Navigation=Navigation;
that.arrayUtils = arrayUtils;
that.LayerDrawingOptions = LayerDrawingOptions;
that.SimpleFillSymbol=SimpleFillSymbol;
that.SimpleLineSymbol=SimpleLineSymbol;
that.Color=Color;
that.Query=Query;
that.Graphic=Graphic;
that.GraphicsLayer=GraphicsLayer;
that.esriConfig=esriConfig;
that.BufferParameters=BufferParameters;
that.SpatialReference=SpatialReference;
that.Extent=Extent;
that.GeometryService=GeometryService;
that.FindTask=FindTask;
that.FindParameters=FindParameters;
that.Point=Point;
that.SimpleMarkerSymbol=SimpleMarkerSymbol;
that.QueryTask=QueryTask;
that.query=query;
that.Draw=Draw;
that.normalizeUtils=normalizeUtils;
/*that.Draw=Draw;
that.Font=Font;
that.TextSymbol=TextSymbol;
that.LengthsParameters=LengthsParameters;
that.Polyline=Polyline;
that.AreasAndLengthsParameters=AreasAndLengthsParameters;
that.domAttr=domAttr;*/
resolve({
	ok:true
});
}).catch(err => {

console.error(err);
});
})
return p;
}
export default app;

2.this is other js:

import esris from './map';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/js/bootstrap';
import arcgis_url from 'Conf/arcgisUrl';
var gpsMap = {};
gpsMap.mapRoad = function(roadName,serverUrl){
var map = esris.map;
//乡镇定位的函数
map.graphics.clear();//清空graphics
//实例化查询参数
var findParams = new esris.FindParameters();
findParams.returnGeometry = true;
findParams.layerIds = [2];//对地级城市和省记性查询
findParams.searchFields = ['GLMC'];//匹配图层中的字段属性
findParams.searchText = roadName;
var findTask = new esris.FindTask(serverUrl);
//进行查询
findTask.execute(findParams,showFindResult);
//查询结果匹配
function showFindResult(queryResult){
if (queryResult.length === 0) {
alert("查询无结果");
return;
}
console.log(queryResult)
$.each(queryResult, function(index, value) {
var pointSymbol = new esris.SimpleMarkerSymbol(//定义点符号
esris.SimpleMarkerSymbol.STYLE_CIRCLE, 10,
new esris.SimpleLineSymbol(esris.SimpleLineSymbol.STYLE_SOLID,
new esris.Color([255,0,0]), 1),
new esris.Color([255,0,0])
);
var outline= new esris.SimpleLineSymbol(esris.SimpleLineSymbol.STYLE_DASHDOT,new esris.Color([255, 0, 0]), 1); //定义面的边界线符号
var PolygonSymbol = new esris.SimpleFillSymbol(esris.SimpleFillSymbol.STYLE_SOLID, outline,new esris.Color([0, 255, 0, 1])); //定义面符号
var graphic ={}; //创建graphic
var locationPoint ={};//创建定位点
var geometry = value.feature.geometry;//获得该图形的形状
if(geometry.type == 'polygon'){
graphic = new esris.Graphic(geometry, PolygonSymbol);
locationPoint=geometry.getCentroid();
}
else if(geometry.type == 'point'){
graphic = new esris.Graphic(geometry, pointSymbol);
locationPoint=geometry;
}
//	map.graphics.add(graphic);
console.log(graphic)
console.log(locationPoint)
// map.centerAndZoom(locationPoint,1);
});
}
}

This is my ideal example.
But I don't know how to do it with a little bit of it?

@andygup

This comment has been minimized.

Copy link
Member

commented Apr 12, 2018

@Huwei1158

Here's an example service that uses a promise esri-map.service.ts, and here's an example of the component that injects it esri-map.component.ts.

Note, the best practice is to defer loading of modules that aren't needed immediately, this is also referred to as lazy loading. Loading all the modules at the same time creates a performance bottleneck that can degrade the end user experience.

@tomwayson

This comment has been minimized.

Copy link
Member

commented Apr 14, 2018

@Huwei1158

Other than what I've suggested above, the pattern I describe here in this is the only other suggestion I have for you. If either of those don't work, then perhaps esri-loader is not the right solution for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.