├── modules ├── imageRecognition.js └── returnImageByExtent.js ├── README.md ├── index.html └── main.js /modules/imageRecognition.js: -------------------------------------------------------------------------------- 1 | // Tensorflow.js code! 2 | 3 | define([], 4 | function() { 5 | return { 6 | getPredictions: function(imageElement) { 7 | async function init() { 8 | let model = await tmImage.load("./models/model.json", "./models/metadata.json"); 9 | const prediction = await model.predict(imageElement); 10 | console.table(prediction); // returns predictions as a table. 11 | }; 12 | 13 | init(); 14 | } 15 | }; 16 | }) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Machine Learning Mapping sample 2 | 3 | This is a quick demo/showcase of the workflow of getting Tensorflow.js working with an image service in the ArcGIS API for JavaScript. 4 | 5 | 6 | ## The Tech 7 | 1. Models trained using [https://teachablemachine.withgoogle.com/train](https://teachablemachine.withgoogle.com/train). 8 | 2. Machine Learning Library is [TensorFlow.js](https://www.tensorflow.org/js) 9 | 3. Mapping API used is the ArcGIS API for JavaScript 10 | 11 | 12 | ## Getting Started 13 | 14 | If you don't know what image service to use... You'd need a [developer subscription](https://pip.pypa.io/en/stable/) to use the following image service - https://tiledbasemaps.arcgis.com/arcgis/rest/services/World_Imagery/MapServer. 15 | 16 | This sample is built to be using the code exported from [Google's Teachable Machine](https://teachablemachine.withgoogle.com/). Simply place the files in the .models/ folder. 17 | -------------------------------------------------------------------------------- /modules/returnImageByExtent.js: -------------------------------------------------------------------------------- 1 | // Fetching image from image service. 2 | 3 | define([ 4 | "esri/layers/MapImageLayer", 5 | "dojo/Deferred" 6 | ], 7 | function(MapImageLayer, Deferred) { 8 | let dataImageObject; 9 | return { 10 | getimageData: function(url, extent) { 11 | dataImageObject = new Deferred(); 12 | 13 | // Imagery layer (/mapserver) 14 | // Note, export needs to be enabled on the REST service for this to work. 15 | const layer = new MapImageLayer({ 16 | url: url 17 | }); 18 | 19 | const height = "500"; 20 | const width = "500"; 21 | 22 | layer.fetchImage(extent, height, width).then(function(data) { 23 | dataImageObject.resolve(data); 24 | }); 25 | 26 | return dataImageObject.promise; 27 | } 28 | }; 29 | }) -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | ArcGIS + Tensorflow sample 8 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
47 | 48 | 49 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | // Main Mapping Application. 2 | 3 | require([ 4 | "esri/Map", 5 | "esri/views/MapView", 6 | "esri/widgets/Sketch/SketchViewModel", 7 | "esri/layers/GraphicsLayer", 8 | 9 | // image recognition (tensorflow) 10 | "./modules/imageRecognition.js", 11 | 12 | // url, extentObject 13 | "./modules/returnImageByExtent.js" 14 | ], function( 15 | Map, 16 | MapView, 17 | SketchViewModel, 18 | GraphicsLayer, 19 | imageRecognition, 20 | returnImageByExtent 21 | ) { 22 | 23 | var worldImageService = ""; // add your image service here! 24 | // Note: https://tiledbasemaps.arcgis.com/arcgis/rest/services/World_Imagery/MapServer requires Developer, or AGOL Subscription. 25 | 26 | var tempGraphicsLayer = new GraphicsLayer(); 27 | 28 | var map = new Map({ 29 | basemap: "satellite", 30 | layers: [tempGraphicsLayer] 31 | }); 32 | 33 | var view = new MapView({ 34 | container: "viewDiv", 35 | map: map, 36 | zoom: 14, 37 | center: [-118.2176276, 33.7445614] 38 | }); 39 | 40 | // Drawing toolbar 41 | var sketchVM = new SketchViewModel({ 42 | layer: tempGraphicsLayer, 43 | view: view 44 | }); 45 | 46 | // On "draw box" 47 | sketchVM.on("create", function(event) { 48 | if (event.state === "complete") { 49 | 50 | // Get image by extent defined. 51 | var image = returnImageByExtent.getimageData(worldImageService, event.graphic.geometry.extent); 52 | 53 | // Once image returned, get predictions. 54 | image.then(function(results) { 55 | imageRecognition.getPredictions(results); 56 | }); 57 | }; 58 | }); 59 | 60 | document.getElementById("draw-button").addEventListener("click", function() { 61 | tempGraphicsLayer.removeAll(); 62 | sketchVM.create("rectangle", { 63 | mode: "freehand" 64 | }); 65 | }) 66 | }); --------------------------------------------------------------------------------