├── .gitignore ├── DomainDataCounter ├── DomainDataCounter.js ├── DomainDataCounter.min.js └── README.md ├── FieldTester ├── FieldTester.js ├── FieldTester.min.js ├── FieldTester_NullOrEmpty.js ├── FieldTester_NullOrEmpty.min.js └── README.md ├── GeometryHelper ├── GeometryHelper.js └── GeometryHelper.min.js ├── LICENSE ├── MapLayerCount ├── MapLayerCount.js ├── MapLayerCount.min.js └── README.md ├── MapLayerData ├── MapLayerData.js ├── MapLayerData.min.js └── README.md ├── MapServiceData ├── MapServiceData.js ├── MapServiceData.min.js └── README.md ├── MapViewer ├── MapViewer.js ├── MapViewer.min.js └── README.md ├── PrintTaskMadeEasy ├── PrintTaskMadeEasy.js ├── PrintTaskMadeEasy.min.js └── README.md ├── QueryHelper ├── QueryHelper.js ├── QueryHelper.min.js └── README.md ├── QuickQueryHelpers ├── AllNoGeo_QueryHelper.js ├── AllNoGeo_QueryHelper.min.js ├── CountThemUp_QueryHelper.js ├── CountThemUp_QueryHelper.min.js ├── GiveMeAll_QueryHelper.js ├── GiveMeAll_QueryHelper.min.js ├── README.md ├── SelectDistinct_QueryHelper.js └── SelectDistinct_QueryHelper.min.js ├── README.md ├── RestSearch ├── README.md ├── RestSearch.js └── RestSearch.min.js ├── SpatialRefCompare ├── README.md ├── SpatialRefCompare.js └── SpatialRefCompare.min.js ├── TileTester ├── README.md ├── TIleTester.js ├── TileTester.min.js ├── TileTester_PreES5.js └── TileTester_PreES5.min.js ├── bookmarklets.html ├── bookmarklets.json ├── gulpfile.js ├── images ├── Install_Chrome.gif ├── Install_Firefox.gif ├── Install_IE.gif └── Install_Opera.gif └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # node stuff 2 | node_modules 3 | 4 | #ignore thumbnails created by windows 5 | Thumbs.db 6 | #Ignore files build by Visual Studio 7 | *.obj 8 | *.exe 9 | *.pdb 10 | *.user 11 | *.aps 12 | *.pch 13 | *.vspscc 14 | *_i.c 15 | *_p.c 16 | *.ncb 17 | *.suo 18 | *.tlb 19 | *.tlh 20 | *.bak 21 | *.cache 22 | *.ilk 23 | *.log 24 | [Bb]in 25 | [Dd]ebug*/ 26 | *.lib 27 | *.sbr 28 | obj/ 29 | [Rr]elease*/ 30 | _ReSharper*/ 31 | [Tt]est[Rr]esult* 32 | .project 33 | -------------------------------------------------------------------------------- /DomainDataCounter/DomainDataCounter.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var url = window.location.href, 3 | d = document; 4 | // ajax function from https://gist.github.com/Xeoncross/7663273 5 | function ajax(u, callback, data, x) { 6 | try { 7 | x = new (this.XMLHttpRequest || ActiveXObject)("MSXML2.XMLHTTP.3.0"); 8 | x.open(data ? "POST" : "GET", u, 1); 9 | x.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 10 | x.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 11 | x.onreadystatechange = function () { 12 | x.readyState > 3 && callback && callback(x.responseText, x); 13 | }; 14 | x.send(data); 15 | } catch (e) { 16 | window.console && console.log(e); 17 | } 18 | } 19 | 20 | function queryMe(f, nodes, tr) { 21 | if (!f.length) { return; } 22 | if (!tr) { 23 | var node = nodes.shift(); 24 | tr = d.createElement("ul"); 25 | node.appendChild(tr); 26 | } 27 | if (f[0].length) { 28 | var item = f[0].shift(), 29 | value = item.type === "esriFieldTypeString" ? "'" + item.code + "'" : item.code, 30 | params = "/query?where=field+%3D+value&returnGeometry=false&returnCountOnly=true&f=json".replace("field", item.field).replace("value", value); 31 | ajax(url + params, 32 | function (response) { 33 | response = JSON.parse(response); 34 | var li = d.createElement("li"); 35 | li.innerHTML = ["", item.name, ": ", response.count, (!response.count ? " !!!" : "")].join(""); 36 | tr.appendChild(li); 37 | if (f[0].length) { queryMe(f, nodes, tr); } 38 | else { 39 | f.shift(); 40 | if (f.length) { 41 | queryMe(f, nodes); 42 | } 43 | } 44 | }); 45 | } 46 | 47 | } 48 | function getFieldList() { 49 | var uls = d.getElementsByTagName("ul"), 50 | labels = [].map.call(uls, function (node) { var h = node; while (h.previousSibling) { h = h.previousSibling; if (h.tagName === "B") break; } return h.innerHTML;}), 51 | i; 52 | for (i = uls.length - 1; i > -1; i--) { 53 | if (/^Fields\:/.test(labels[i])) { 54 | return [].map.call(uls[i].children, function (j) {return j;}); 55 | } 56 | } 57 | return null; 58 | } 59 | function onLoad(response) { 60 | var fieldNodes, fields = [], i, field; 61 | response = JSON.parse(response); 62 | if (response.fields) { 63 | fieldNodes = getFieldList(); 64 | //filter fields with domains 65 | for (i = response.fields.length - 1; i > -1; i--) { 66 | field = response.fields[i]; 67 | if (field.domain) { 68 | if (field.domain.codedValues) { 69 | fields.push(field.domain.codedValues.map(function (item) { 70 | item.field = field.name; 71 | item.type = field.type; 72 | return item; 73 | })); 74 | } else if (field.domain.range) { 75 | // handle field.domain.range, probably with a histogram 76 | } 77 | } else { 78 | // cut out field nodes that don't have a domain 79 | fieldNodes.splice(i, 1); 80 | } 81 | } 82 | fields.reverse(); 83 | queryMe(fields, fieldNodes, null); 84 | } 85 | } 86 | 87 | if (/\d+\/?$/.test(url)) { 88 | ajax(url + "?f=json", onLoad); 89 | } else { 90 | if (!/(map|feature)server\/?$/i.test(url)) { 91 | alert("Pick a map/feature service and layer"); 92 | } else { 93 | alert("Pick a valid layer"); 94 | } 95 | } 96 | }()); 97 | -------------------------------------------------------------------------------- /DomainDataCounter/DomainDataCounter.min.js: -------------------------------------------------------------------------------- 1 | (function(){var b=window.location.href,g=document;function f(h,k,i,d){try{d=new (this.XMLHttpRequest||ActiveXObject)("MSXML2.XMLHTTP.3.0");d.open(i?"POST":"GET",h,1);d.setRequestHeader("X-Requested-With","XMLHttpRequest");d.setRequestHeader("Content-type","application/x-www-form-urlencoded");d.onreadystatechange=function(){d.readyState>3&&k&&k(d.responseText,d)};d.send(i)}catch(j){window.console&&console.log(j)}}function c(l,d,k){if(!l.length){return}if(!k){var i=d.shift();k=g.createElement("ul");i.appendChild(k)}if(l[0].length){var h=l[0].shift(),j=h.type==="esriFieldTypeString"?"%27"+h.code+"%27":h.code,m="/query?where=field+%3D+value&returnGeometry=false&returnCountOnly=true&f=json".replace("field",h.field).replace("value",j);f(b+m,function(o){o=JSON.parse(o);var n=g.createElement("li");n.innerHTML=["",h.name,": ",o.count,(!o.count?" !!!":"")].join("");k.appendChild(n);if(l[0].length){c(l,d,k)}else{l.shift();if(l.length){c(l,d)}}})}}function a(){var h=g.getElementsByTagName("ul"),j=[].map.call(h,function(k){var i=k;while(i.previousSibling){i=i.previousSibling;if(i.tagName==="B"){break}}return i.innerHTML}),d;for(d=h.length-1;d>-1;d--){if(/^Fields\:/.test(j[d])){return[].map.call(h[d].children,function(i){return i})}}return null}function e(j){var h,d=[],k,l;j=JSON.parse(j);if(j.fields){h=a();for(k=j.fields.length-1;k>-1;k--){l=j.fields[k];if(l.domain){if(l.domain.codedValues){d.push(l.domain.codedValues.map(function(i){i.field=l.name;i.type=l.type;return i}))}else{if(l.domain.range){}}}else{h.splice(k,1)}}d.reverse();c(d,h,null)}}if(/\d+\/?$/.test(b)){f(b+"?f=json",e)}else{if(!/(map|feature)server\/?$/i.test(b)){alert("Pick a map/feature service and layer")}else{alert("Pick a valid layer")}}}()); 2 | -------------------------------------------------------------------------------- /DomainDataCounter/README.md: -------------------------------------------------------------------------------- 1 | # Domain Data Counter (ESRI REST Diagnostics) 2 | 3 | Bookmarklet to test ArcGIS REST Service fields with domains, counting the number of features with each domain value assigned to a field. 4 | 5 | ## Features 6 | 7 | This bookmarklet scans an ArcGIS Server MapService layer for fields that have domains. When it finds a field with a domain, it loops through each domain value and queries the layer for the number of features that have that domain value. It then presents the data on the REST html page for that layer. 8 | 9 | ## Instructions 10 | 11 | ### Installation 12 | 13 | Installation on the browser is as simple as adding a bookmark. From the [ESRI Rest Diagnostics](http://raykendo.github.io/ESRI_REST_Diagnostics/) page... 14 | 15 | - Chrome: drag the anchor link to your browser toolbar. 16 | - Firefox: right-click on the link and select "Bookmark this link". 17 | - IE: right-click on the link and select "Add to Favorites". 18 | - Safari: untested. 19 | - Opera: drag the anchor link to your browser toolbar. 20 | 21 | ### Basic Use 22 | 23 | Navigate to an ArcGIS Server REST service endpoint in your browser. Drill down to a Map Service or a Feature Service layer. [Click here for an example](http://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/MapServer/0). Call the bookmarklet from your bookmark bar, and let it run. 24 | 25 | The bookmarklets requests field properties for the layer and finds fields with domains. For each coded value domain, the bookmarklet queries for the count of features that have that coded value. It then writes the values on the HTML page for the REST service. 26 | 27 | ## Requirements 28 | 29 | - Desktop browser (IE8+, Chrome, Firefox) 30 | - Security settings that support bookmarklets. 31 | - Access to an ArcGIS Server REST endpoint in browser. 32 | 33 | ## Notes 34 | 35 | - Currently untested on Safari. Please give me feedback if you try it. 36 | - Not tested on mobile/tablet browsers, since I'm not sure how bookmarklets work with those. 37 | 38 | ## Contributing 39 | 40 | Anyone is welcome to contribute to this project. 41 | 42 | ## Licensing 43 | 44 | This is currently licensed under the MIT Licensing ([See License here](https://github.com/raykendo/ESRI_REST_Diagnostics/blob/master/LICENSE)). 45 | -------------------------------------------------------------------------------- /FieldTester/FieldTester.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | "use strict"; 3 | var url = window.location.href, 4 | d = document; 5 | // ajax function from https://gist.github.com/Xeoncross/7663273 6 | function ajax(u, callback, data, x) { 7 | try { 8 | x = new(window.XMLHttpRequest || ActiveXObject)("MSXML2.XMLHTTP.3.0"); 9 | x.open(data ? "POST" : "GET", u, 1); 10 | x.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 11 | x.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 12 | x.onreadystatechange = function () { 13 | x.readyState > 3 && callback && callback(x.responseText, x); 14 | }; 15 | x.send(data); 16 | } catch (e) { 17 | window.console && console.log(e); 18 | } 19 | } 20 | function responseTime (timeValue) { 21 | var timeDiff = Date.now() - timeValue; 22 | return "" + (timeDiff > 1000 ? timeDiff / 1000 : timeDiff + "m") + "s"; 23 | } 24 | function queryMe (f, nodes) { 25 | if (!f.length) { return; } 26 | var field = f.shift(), 27 | node = nodes.shift(), 28 | params = "/query?where=not+field+is+null&returnGeometry=false&returnCountOnly=true&f=json".replace("field", field.name), 29 | timeCheck = Date.now(); 30 | ajax(url + params, 31 | function (response) { 32 | response = JSON.parse(response); 33 | var tr = d.createElement("ul"); 34 | tr.innerHTML = "
  • " + ["Features with values: " + response.count + (!response.count ? " !!!":""), "Response Time: " + responseTime(timeCheck)].join("
  • ") + "
  • "; 35 | node.appendChild(tr); 36 | if (f.length) { queryMe(f, nodes); } 37 | }); 38 | } 39 | function getFieldList () { 40 | var uls = d.getElementsByTagName("ul"), 41 | labels = [].map.call(uls, function (node) { var h = node; while (h.previousSibling) { h = h.previousSibling; if (h.tagName === "B") break; } return h.innerHTML;}), 42 | i; 43 | for (i = uls.length - 1; i > -1; i--) { 44 | if (/^Fields\:/.test(labels[i])) { 45 | return [].map.call(uls[i].children, function (j) {return j;}); 46 | } 47 | } 48 | return null; 49 | } 50 | function onLoad(response) { 51 | response = JSON.parse(response); 52 | if (response.fields) { 53 | // run query 54 | queryMe(response.fields, getFieldList()); 55 | } 56 | } 57 | 58 | if (/\d+\/?$/.test(url)) { 59 | ajax(url + "?f=json", onLoad); 60 | } else { 61 | if (!/(map|feature)server\/?$/i.test(url)) { 62 | alert("Pick a map/feature service and layer"); 63 | } else { 64 | alert("Pick a valid layer"); 65 | } 66 | } 67 | }()); 68 | -------------------------------------------------------------------------------- /FieldTester/FieldTester.min.js: -------------------------------------------------------------------------------- 1 | (function(){"use strict";var b=window.location.href,h=document;function g(i,l,j,d){try{d=new (window.XMLHttpRequest||ActiveXObject)("MSXML2.XMLHTTP.3.0");d.open(j?"POST":"GET",i,1);d.setRequestHeader("X-Requested-With","XMLHttpRequest");d.setRequestHeader("Content-type","application/x-www-form-urlencoded");d.onreadystatechange=function(){d.readyState>3&&l&&l(d.responseText,d)};d.send(j)}catch(k){window.console&&console.log(k)}}function f(d){var i=Date.now()-d;return""+(i>1000?i/1000:i+"m")+"s"}function c(j,d){if(!j.length){return}var k=j.shift(),i=d.shift(),l="/query?where=not+field+is+null&returnGeometry=false&returnCountOnly=true&f=json".replace("field",k.name),m=Date.now();g(b+l,function(n){n=JSON.parse(n);var o=h.createElement("ul");o.innerHTML="
  • "+["Features with values: "+n.count+(!n.count?" !!!":""),"Response Time: "+f(m)].join("
  • ")+"
  • ";i.appendChild(o);if(j.length){c(j,d)}})}function a(){var j=h.getElementsByTagName("ul"),k=[].map.call(j,function(l){var i=l;while(i.previousSibling){i=i.previousSibling;if(i.tagName==="B"){break}}return i.innerHTML}),d;for(d=j.length-1;d>-1;d--){if(/^Fields\:/.test(k[d])){return[].map.call(j[d].children,function(i){return i})}}return null}function e(d){d=JSON.parse(d);if(d.fields){c(d.fields,a())}}if(/\d+\/?$/.test(b)){g(b+"?f=json",e)}else{if(!/(map|feature)server\/?$/i.test(b)){alert("Pick a map/feature service and layer")}else{alert("Pick a valid layer")}}}()); 2 | -------------------------------------------------------------------------------- /FieldTester/FieldTester_NullOrEmpty.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | "use strict"; 3 | var url = window.location.href, 4 | d = document; 5 | // ajax function from https://gist.github.com/Xeoncross/7663273 6 | function ajax(u, callback, data, x) { 7 | try { 8 | x = new(window.XMLHttpRequest || ActiveXObject)("MSXML2.XMLHTTP.3.0"); 9 | x.open(data ? "POST" : "GET", u, 1); 10 | x.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 11 | x.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 12 | x.onreadystatechange = function () { 13 | x.readyState > 3 && callback && callback(JSON.parse(x.responseText), x); 14 | }; 15 | x.send(data) 16 | } catch (e) { 17 | window.console && console.log(e); 18 | } 19 | } 20 | function responseTime (timeValue) { 21 | var timeDiff = Date.now() - timeValue; 22 | return "" + (timeDiff > 1000 ? timeDiff / 1000 : timeDiff + "m") + "s"; 23 | } 24 | function queryMe (f, nodes) { 25 | if (!f.length) { return; } 26 | var field = f.shift(), 27 | node = nodes.shift(), 28 | params = "/query?where=not+field+is+null&returnGeometry=false&returnCountOnly=true&f=json".replace(/field/g, field.name), 29 | timeCheck = Date.now(); 30 | if (field.type === "esriFieldTypeString") { 31 | params = params.replace("is+null", "is+null+and+" + field.name + "+<>%27%27"); 32 | } 33 | ajax(url + params, 34 | function (response) { 35 | response = JSON.parse(response); 36 | var tr = d.createElement("ul"); 37 | tr.innerHTML = "
  • " + ["Features with values: " + response.count + (!response.count ? " !!!":""), "Response Time: " + responseTime(timeCheck)].join("
  • ") + "
  • "; 38 | node.appendChild(tr); 39 | if (f.length) { queryMe(f, nodes); } 40 | }); 41 | } 42 | function getFieldList () { 43 | var uls = d.getElementsByTagName("ul"), 44 | labels = [].map.call(uls, function (node) { var h = node; while (h.previousSibling) { h = h.previousSibling; if (h.tagName === "B") break; } return h.innerHTML;}), 45 | i; 46 | for (i = uls.length - 1; i > -1; i--) { 47 | if (/^Fields\:/.test(labels[i])) { 48 | return [].map.call(uls[i].children, function (j) {return j;}); 49 | } 50 | } 51 | return null; 52 | } 53 | function onLoad(response) { 54 | if (response.fields) { 55 | // run query 56 | queryMe(response.fields, getFieldList()); 57 | } 58 | } 59 | 60 | if (/\d+\/?$/.test(url)) { 61 | ajax(url + "?f=json", onLoad); 62 | } else { 63 | if (!/(map|feature)server\/?$/i.test(url)) { 64 | alert("Pick a map/feature service and layer"); 65 | } else { 66 | alert("Pick a valid layer"); 67 | } 68 | } 69 | }()); 70 | -------------------------------------------------------------------------------- /FieldTester/FieldTester_NullOrEmpty.min.js: -------------------------------------------------------------------------------- 1 | (function(){"use strict";var b=window.location.href,h=document;function g(i,l,j,d){try{d=new (window.XMLHttpRequest||ActiveXObject)("MSXML2.XMLHTTP.3.0");d.open(j?"POST":"GET",i,1);d.setRequestHeader("X-Requested-With","XMLHttpRequest");d.setRequestHeader("Content-type","application/x-www-form-urlencoded");d.onreadystatechange=function(){d.readyState>3&&l&&l(d.responseText,d)};d.send(j)}catch(k){window.console&&console.log(k)}}function f(d){var i=Date.now()-d;return""+(i>1000?i/1000:i+"m")+"s"}function c(j,d){if(!j.length){return}var k=j.shift(),i=d.shift(),l="/query?where=not+field+is+null&returnGeometry=false&returnCountOnly=true&f=json".replace(/field/g,k.name),m=Date.now();if(k.type==="esriFieldTypeString"){l=l.replace("is+null","is+null+and+"+k.name+"+<>%27%27")}g(b+l,function(n){n=JSON.parse(n);var o=h.createElement("ul");o.innerHTML="
  • "+["Features with populated values: "+n.count+(!n.count?" !!!":""),"Response Time: "+f(m)].join("
  • ")+"
  • ";i.appendChild(o);if(j.length){c(j,d)}})}function a(){var j=h.getElementsByTagName("ul"),k=[].map.call(j,function(l){var i=l;while(i.previousSibling){i=i.previousSibling;if(i.tagName==="B"){break}}return i.innerHTML}),d;for(d=j.length-1;d>-1;d--){if(/^Fields\:/.test(k[d])){return[].map.call(j[d].children,function(i){return i})}}return null}function e(d){d=JSON.parse(d);if(d.fields){c(d.fields,a())}}if(/\d+\/?$/.test(b)){g(b+"?f=json",e)}else{if(!/(map|feature)server\/?$/i.test(b)){alert("Pick a map/feature service and layer")}else{alert("Pick a valid layer")}}}()); 2 | -------------------------------------------------------------------------------- /FieldTester/README.md: -------------------------------------------------------------------------------- 1 | # Field Tester (ESRI REST Diagnostics) 2 | 3 | Bookmarklets to test for field values populated by data. 4 | 5 | ## Features 6 | 7 | The bookmarklets count the number of features with values and return server response times for each field within an ArcGIS Server Map Service or Feature Service layer. The first tests for non-null data, while the second also checks for empty strings. You can use these bookmarklets to test data integrity and of each field, and roughly expected return times for queries. 8 | 9 | ## Instructions 10 | 11 | ### Installation 12 | 13 | Installation on the browser is as simple as adding a bookmark. From the [ESRI Rest Diagnostics](http://raykendo.github.io/ESRI_REST_Diagnostics/) page... 14 | 15 | - Chrome: drag the anchor link to your browser toolbar. 16 | - Firefox: right-click on the link and select "Bookmark this link". 17 | - IE: right-click on the link and select "Add to Favorites". 18 | - Safari: untested. 19 | - Opera: drag the anchor link to your browser toolbar. 20 | 21 | ### Basic Use 22 | 23 | Navigate to an ArcGIS Server REST service endpoint in your browser. Drill down to a Map Service or a Feature Service layer. [Click here for an example](http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3). Call the bookmarklet from your bookmark bar, and let it run. 24 | 25 | The bookmarklets systematically queries for the count of each field value that isn't null, then adds notes to each field with the number of features with values, as well as the number of milliseconds it took to return the features. The first bookmarklet screens out null values, while the second screens out null and empty string values. 26 | 27 | ## Requirements 28 | 29 | - Desktop browser (IE8+, Chrome, Firefox) 30 | - Security settings that support bookmarklets. 31 | - Access to an ArcGIS Server REST endpoint in browser. 32 | 33 | ## Notes 34 | 35 | - Currently untested on Safari. Please give me feedback if you try it. 36 | - Not tested on mobile/tablet browsers, since I'm not sure how bookmarklets work with those. 37 | 38 | ## Contributing 39 | 40 | Anyone is welcome to contribute to this project. 41 | 42 | ## Licensing 43 | 44 | This is currently licensed under the MIT Licensing ([See License here](https://github.com/raykendo/ESRI_REST_Diagnostics/blob/master/LICENSE)). 45 | -------------------------------------------------------------------------------- /GeometryHelper/GeometryHelper.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var url = "http://js.arcgis.com/3.8/", 3 | css = url + "js/esri/css/esri.css", 4 | d = document, 5 | style1, scr1; 6 | function loadMe() { 7 | require(["dojo/ready", "dojo/dom-construct", "dojo/query", "dojo/json", "esri/request", "esri/toolbars/draw", 8 | "esri/map", "esri/layers/ArcGISDynamicMapServiceLayer", "esri/layers/ArcGISTiledMapServiceLayer" 9 | ], function (ready, domConstruct, dojoQuery, JSON, esriRequest, Draw, Map, Dynamic, Tiled) { 10 | ready(function () { 11 | var wl = window.location, url = wl.href.replace(wl.search, "").replace(/\/\d+\/query\/?$/i, ""), 12 | geoBlank = dojoQuery("textarea[name=\"geometry\"]"), 13 | geoSelect = dojoQuery("select[name=\"geometryType\"]")[0]; 14 | esriRequest({ 15 | url: url, 16 | handleAs: "json", 17 | content: {f: "json"} 18 | }).then(function (resp) { 19 | var div = domConstruct.create("div", { 20 | style: "position:fixed;bottom:15%;top:15%;right:0;width:40%;border:1px solid #F88;padding:5px;background:#fff;overflow:auto;", 21 | innerHTML: "
    " 22 | }, d.body), 23 | map = new Map("map",{}), 24 | layer = resp.singleFusedMapCache ? new Tiled(url) : new Dynamic(url), 25 | xlator = {btnpt: Draw.POINT,btnln: Draw.POLYLINE,btnpg:Draw.POLYGON,btnex:Draw.EXTENT}, draw; 26 | map.on("load", function () { 27 | draw = new Draw(map); 28 | dojoQuery("button", div).on("click", function (evt) { 29 | if (evt.target.id in xlator) { 30 | draw.activate(xlator[evt.target.id]); 31 | } else { 32 | map.destroy(); 33 | domConstruct.destroy(div); 34 | } 35 | }); 36 | draw.on("draw-end", function (drawn) { 37 | var i, xlator = {point: "esriGeometryPoint", multipoint: "esriGeometryMultipoint", polyline: "esriGeometryPolyline", polygon: "esriGeometryPolygon", extent: "esriGeometryEnvelope"}; 38 | for (i = geoSelect.options.length - 1; i > -1; i--) { 39 | if (geoSelect.options[i].value === xlator[drawn.geometry.type]) { 40 | geoSelect.selectedIndex = i; 41 | break; 42 | } 43 | } 44 | geoBlank.value = JSON.stringify(drawn.geometry.toJson()); 45 | 46 | }); 47 | }); 48 | map.addLayer(layer); 49 | geoBlank = geoBlank && geoBlank.length ? geoBlank[0] : domConstruct.create("textarea", {}, div); 50 | }); 51 | }); 52 | }); 53 | } 54 | function scriptLoaded(url) { 55 | var scripts = d.getElementsByTagName("script"), i; 56 | for (i = scripts.length - 1; i > -1; i--) { 57 | if (scripts[i].src === url) { return true; } 58 | } 59 | return false; 60 | } 61 | if (!scriptLoaded(url)) { 62 | style1 = d.createElement("link"); 63 | style1.setAttribute("rel", "stylesheet"); 64 | style1.setAttribute("type", "text/css"); 65 | style1.href = css; 66 | d.head.appendChild(style1); 67 | scr1 = d.createElement("script"); 68 | scr1.setAttribute("type", "text/javascript"); 69 | scr1.onload = loadMe; 70 | scr1.setAttribute("src", url); 71 | d.body.appendChild(scr1); 72 | } else { 73 | loadMe(); 74 | } 75 | }()); -------------------------------------------------------------------------------- /GeometryHelper/GeometryHelper.min.js: -------------------------------------------------------------------------------- 1 | (function(){var url="http://js.arcgis.com/3.8/",css=url+"js/esri/css/esri.css",d=document,style1,scr1;function loadMe(){require(["dojo/ready","dojo/dom-construct","dojo/query","dojo/json","esri/request","esri/toolbars/draw","esri/map","esri/layers/ArcGISDynamicMapServiceLayer","esri/layers/ArcGISTiledMapServiceLayer"],function(ready,dC,dQ,JSON,esriRequest,Draw,Map,Dynamic,Tiled){ready(function(){var wl=window.location,url=wl.href.replace(wl.search,"").replace(/\/\d+\/query\/?$/i,""),geoBlank=dQ("textarea[name=\"geometry\"]"),geoSelect=dQ("select[name=\"geometryType\"]")[0];esriRequest({url:url,handleAs:"json",content:{f:"json"}}).then(function(resp){var div=dC.create("div",{style:"position:fixed;bottom:15%;top:15%;right:0;width:40%;border:1px solid #F88;padding:5px;background:#fff;overflow:auto;",innerHTML:"
    "},d.body),map=new Map("map",{}),layer=resp.singleFusedMapCache?new Tiled(url):new Dynamic(url),xlator={btnpt:Draw.POINT,btnln:Draw.POLYLINE,btnpg:Draw.POLYGON,btnex:Draw.EXTENT},draw;map.on("load",function(){draw=new Draw(map);dQ("button",div).on("click",function(evt){if(evt.target.id in xlator){draw.activate(xlator[evt.target.id]);}else{map.destroy();dC.destroy(div);}});draw.on("draw-end",function(drawn){var i,xlator={point:"esriGeometryPoint",multipoint:"esriGeometryMultipoint",polyline:"esriGeometryPolyline",polygon:"esriGeometryPolygon",extent:"esriGeometryEnvelope"};for(i=geoSelect.options.length-1;i>-1;i--){if(geoSelect.options[i].value===xlator[drawn.geometry.type]){geoSelect.selectedIndex=i;break;}}geoBlank.value=JSON.stringify(drawn.geometry.toJson());});});map.addLayer(layer);geoBlank=geoBlank&&geoBlank.length?geoBlank[0]:dC.create("textarea",{},div);});});});}function scriptLoaded(url){var scripts=d.getElementsByTagName("script"),i;for(i=scripts.length-1;i>-1;i--){if(scripts[i].src===url){return true;}}return false;}if(!scriptLoaded(url)){style1=d.createElement("link");style1.setAttribute("rel","stylesheet");style1.setAttribute("type","text/css");style1.href=css;d.head.appendChild(style1);scr1=d.createElement("script");scr1.setAttribute("type","text/javascript");scr1.onload=loadMe;scr1.setAttribute("src",url);d.body.appendChild(scr1);}else{loadMe();}}()); -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Ken Doman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /MapLayerCount/MapLayerCount.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var d = document, 3 | tags = d.getElementsByTagName("a"), 4 | urls = [], 5 | i; 6 | // ajax function from https://gist.github.com/Xeoncross/7663273 7 | function ajax(u, callback, data, x) { 8 | try { 9 | x = new (this.XMLHttpRequest || ActiveXObject)("MSXML2.XMLHTTP.3.0"); 10 | x.open(data ? "POST" : "GET", u, 1); 11 | x.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 12 | x.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 13 | x.onreadystatechange = function () { 14 | x.readyState > 3 && callback && callback(JSON.parse(x.responseText), x); 15 | }; 16 | x.send(data); 17 | } catch (e) { 18 | window.console && console.log(e); 19 | } 20 | } 21 | function add(frag, title, content) { 22 | var li = d.createElement("li"); 23 | li.innerHTML = ["", title, "", content != null ? ": " : "", content].join(""); 24 | frag.appendChild(li); 25 | } 26 | function queryMe(f) { 27 | if (!f.length) { return; } 28 | var data = f.shift(); 29 | ajax(data.url + "?f=json", 30 | function (response) { 31 | 32 | var ul = d.createElement("ul"), 33 | oid = null, 34 | shape = null, 35 | newURL = data.url + "/query?where=not+field+is+null&returnGeometry=false&returnCountOnly=true&f=json", 36 | j; 37 | 38 | if (response.fields) { 39 | 40 | for (j = 0; j < response.fields.length; j++) { 41 | switch(response.fields[j].type) { 42 | case "esriFieldTypeOID": 43 | case "": 44 | oid = response.fields[j].name; 45 | break; 46 | case "esriFieldTypeGeometry": 47 | shape = response.fields[j].name; 48 | break; 49 | } 50 | if (oid && shape) { break; } 51 | } 52 | } 53 | 54 | if (oid) { 55 | ajax(newURL.replace("field", oid), function (counter) { 56 | add(ul, "Number of Results", counter.count); 57 | }); 58 | } 59 | if (shape) { 60 | ajax(newURL.replace("field", shape), function (counter) { 61 | add(ul, "With geometry", counter.count); 62 | }); 63 | } 64 | if (response.fields && !oid && !shape) { 65 | add(ul, "No Queryable Results"); 66 | } 67 | 68 | tags[data.i].parentNode.appendChild(ul); 69 | 70 | if (f.length) { 71 | queryMe(f); 72 | } 73 | }); 74 | } 75 | if (/(map|feature)server\/?$/i.test(window.location.href)) { 76 | for (i = 0; i < tags.length; i++) { 77 | // filter links for map service layers (index number at end); 78 | if (/server\/\d+\/?$/i.test(tags[i].href)) { 79 | urls.push({ i: i, url: tags[i].href }); 80 | } 81 | 82 | } 83 | if (urls && urls.length) { 84 | queryMe(urls); 85 | } 86 | 87 | } else { 88 | if (/server\/\d+\/?$/i.test(window.location.href)) { 89 | alert("Go to the parent map service layer."); 90 | } else { 91 | alert("Pick a valid layer"); 92 | } 93 | } 94 | }()); -------------------------------------------------------------------------------- /MapLayerCount/MapLayerCount.min.js: -------------------------------------------------------------------------------- 1 | (function(){var d=document,tags=d.getElementsByTagName("a"),urls=[],i;function ajax(u,callback,data,x){try{x=new(this.XMLHttpRequest||ActiveXObject)("MSXML2.XMLHTTP.3.0");x.open(data?"POST":"GET",u,1);x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Content-type","application/x-www-form-urlencoded");x.onreadystatechange=function(){x.readyState>3&&callback&&callback(JSON.parse(x.responseText),x);};x.send(data);}catch(e){window.console&&console.log(e);}}function add(frag,t,ct){var li=d.createElement("li");li.innerHTML=["",t,"",ct!=null?": ":"",ct].join("");frag.appendChild(li);}function queryMe(f){if(!f.length){return;}var data=f.shift();ajax(data.url+"?f=json",function(r){var ul=d.createElement("ul"),oid=null,shape=null,newURL=data.url+"/query?where=not+field+is+null&returnGeometry=false&returnCountOnly=true&f=json",j;if(r.fields){for(j=0;j 3 && callback && callback(x.responseText, x); 15 | }; 16 | x.send(data); 17 | } catch (e) { 18 | window.console && console.log(e); 19 | } 20 | } 21 | function add(frag, title, content) { 22 | var li = d.createElement("li"); 23 | li.innerHTML = ["", title, "", content ? ": " : "", content].join(""); 24 | frag.appendChild(li); 25 | } 26 | function queryMe(f) { 27 | if (!f.length) { return; } 28 | var data = f.shift(); 29 | ajax(data.url + "?f=json", 30 | function (response) { 31 | var dF = d.createDocumentFragment(), 32 | ul = d.createElement("ul"); 33 | response = JSON.parse(response); 34 | add(dF, "Geometry", response.geometryType.replace("esriGeometry", "")); 35 | add(dF, "Min Scale", response.minScale || "None"); 36 | add(dF, "Max Scale", response.maxScale || "None"); 37 | if (response.definitionExpression) { 38 | add(dF, "Definition Expression", response.definitionExpression); 39 | } 40 | add(dF, "Visible by default", response.defaultVisibility.toString()); 41 | if (response.hasAttachments) { 42 | add(dF, "Has Attachments"); 43 | } 44 | if (response.hasLabels) { 45 | add(dF, "Has Labels"); 46 | } 47 | if (response.supportsStatistics) { 48 | add(dF, "Supports Statistics"); 49 | } 50 | if (response.supportsAdvancedQueries) { 51 | add(dF, "Supports Advanced Queries"); 52 | } 53 | if (response.relationships && response.relationships.length) { 54 | add(dF, "Has Relationships"); 55 | } 56 | add(dF, "Versioned Data", response.isDataVersioned ? "Yes" : "No"); 57 | 58 | tags[data.i].parentNode.appendChild(ul); 59 | ul.appendChild(dF); 60 | if (f.length) { 61 | queryMe(f); 62 | } 63 | }); 64 | } 65 | 66 | if (/(map|feature)server\/?$/i.test(window.location.href)) { 67 | for (i = 0; i < tags.length; i++) { 68 | // filter links for map service layers (index number at end); 69 | if (/server\/\d+\/?$/i.test(tags[i].href)) { 70 | urls.push({ i: i, url: tags[i].href }); 71 | } 72 | 73 | if (urls && urls.length) { 74 | queryMe(urls); 75 | } 76 | } 77 | 78 | } else { 79 | if (/server\/\d+\/?$/i.test(window.location.href)) { 80 | alert("Go to the parent map service layer."); 81 | } else { 82 | alert("Pick a valid layer"); 83 | } 84 | } 85 | }()); -------------------------------------------------------------------------------- /MapLayerData/MapLayerData.min.js: -------------------------------------------------------------------------------- 1 | (function(){var d=document,tags=d.getElementsByTagName("a"),urls=[],i;function ajax(u,callback,data,x){try{x=new(this.XMLHttpRequest||ActiveXObject)("MSXML2.XMLHTTP.3.0");x.open(data?"POST":"GET",u,1);x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Content-type","application/x-www-form-urlencoded");x.onreadystatechange=function(){x.readyState>3&&callback&&callback(x.responseText,x);};x.send(data);}catch(e){window.console&&console.log(e);}}function add(frag,t,c){var li=d.createElement("li");li.innerHTML=["",t,"",c?": ":"",c].join("");frag.appendChild(li);}function queryMe(f){if(!f.length){return;}var data=f.shift();ajax(data.url+"?f=json",function(r){var dF=d.createDocumentFragment(),ul=d.createElement("ul");r=JSON.parse(r);add(dF,"Geometry",r.geometryType.replace("esriGeometry",""));add(dF,"Min Scale",r.minScale||"None");add(dF,"Max Scale",r.maxScale||"None");if(r.definitionExpression){add(dF,"Definition Expression",r.definitionExpression);}add(dF,"Visible by default",r.defaultVisibility.toString());if(r.hasAttachments){add(dF,"Has Attachments");}if(r.hasLabels){add(dF,"Has Labels");}if(r.supportsStatistics){add(dF,"Supports Statistics");}if(r.supportsAdvancedQueries){add(dF,"Supports Advanced Queries");}if(r.relationships&&r.relationships.length){add(dF,"Has Relationships");}add(dF,"Versioned Data",r.isDataVersioned?"Yes":"No");tags[data.i].parentNode.appendChild(ul);ul.appendChild(dF);if(f.length){queryMe(f);}});}if(/(map|feature)server\/?$/i.test(window.location.href)){for(i=0;i 3 && callback && callback(x.responseText, x); 15 | }; 16 | x.send(data); 17 | } catch (e) { 18 | window.console && console.log(e); 19 | } 20 | } 21 | function add(node, title, content, hideifContentFalse, hideContent) { 22 | if (hideifContentFalse && !content) { return; } 23 | var li = d.createElement("li"); 24 | li.innerHTML = ["", title, "", (hideContent ? "": ": " + (content instanceof Object ? JSON.stringify(content) : content))].join(""); 25 | node.appendChild(li); 26 | } 27 | function addSubList(node, title, content) { 28 | var li = d.createElement("li"), ul = d.createElement("ul"), i; 29 | li.innerHTML = "" + title + ":"; 30 | for (i in content) { 31 | add(ul, i, content[i], 1); 32 | } 33 | li.appendChild(ul); 34 | node.appendChild(li); 35 | } 36 | function queryMe(f) { 37 | if (!f.length) { return; } 38 | var data = f.shift(); 39 | ajax(data.url + "?f=json", 40 | function (response) { 41 | var dF = d.createDocumentFragment(), 42 | ul = d.createElement("ul"); 43 | response = JSON.parse(response); 44 | add(dF, "Description", response.description, true); 45 | add(dF, "Service Description", response.serviceDescription, true); 46 | add(dF, "©", response.copyrightText, true); 47 | add(dF, "Supports Dynamic Layers", 0, response.supportsDynamicLayers, 1); 48 | add(dF, "# Layers", response.layers ? response.layers.length : 0); 49 | add(dF, "# Tables", response.tables ? response.tables.length : 0, 1); 50 | add(dF, "Tiled or Dynamic", response.tileInfo ? " tiled" : " dynamic"); 51 | add(dF, "Spatial Reference", JSON.stringify(response.spatialReference || "none")); 52 | add(dF, "Min Scale", response.minScale || "None"); 53 | add(dF, "Max Scale", response.maxScale || "None"); 54 | addSubList(dF, "Initial Extent", response.initialExtent); 55 | addSubList(dF, "Full Extent", response.fullExtent); 56 | add(dF, "Units", response.units.replace("esri", "")); 57 | addSubList(dF, "Document Info", response.documentInfo); 58 | add(dF, "Max Record Count", response.maxRecordCount); 59 | tags[data.i].parentNode.appendChild(ul); 60 | ul.appendChild(dF); 61 | if (f.length) { 62 | queryMe(f); 63 | } 64 | }); 65 | } 66 | 67 | for (i = 0; i < tags.length; i++) { 68 | // filter links for map service layers (index number at end); 69 | if (/(map|feature|image|mobile)server\/?$/i.test(tags[i].href)) { 70 | urls.push({ i: i, url: tags[i].href }); 71 | } 72 | 73 | if (urls && urls.length) { 74 | queryMe(urls); 75 | } 76 | } 77 | }()); -------------------------------------------------------------------------------- /MapServiceData/MapServiceData.min.js: -------------------------------------------------------------------------------- 1 | (function(){var d=document,tags=d.getElementsByTagName("a"),urls=[],i;function ajax(u,callback,data,x){try{x=new(this.XMLHttpRequest||ActiveXObject)("MSXML2.XMLHTTP.3.0");x.open(data?"POST":"GET",u,1);x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Content-type","application/x-www-form-urlencoded");x.onreadystatechange=function(){x.readyState>3&&callback&&callback(x.responseText,x);};x.send(data);}catch(e){window.console&&console.log(e);}}function add(nd,t,ct,hF,hC){if(hF&&!ct){return;}var li=d.createElement("li");li.innerHTML=["",t,"",(hC?"":": "+(ct instanceof Object?JSON.stringify(ct):ct))].join("");nd.appendChild(li);}function aSL(nd,t,ct){var li=d.createElement("li"),ul=d.createElement("ul"),i;li.innerHTML=""+t+":";for(i in ct){add(ul,i,ct[i],1);}li.appendChild(ul);nd.appendChild(li);}function queryMe(f){if(!f.length){return;}var data=f.shift();ajax(data.url+"?f=json",function(r){var dF=d.createDocumentFragment(),ul=d.createElement("ul");r=JSON.parse(r);add(dF,"Description",r.description,true);add(dF,"Service Description",r.serviceDescription,true);add(dF,"©",r.copyrightText,true);add(dF,"Supports Dynamic Layers",0,r.supportsDynamicLayers,1);add(dF,"# Layers",r.layers?r.layers.length:0);add(dF,"# Tables",r.tables?r.tables.length:0,1);add(dF,"Tiled or Dynamic",r.tileInfo?" tiled":" dynamic");add(dF,"Spatial Reference",JSON.stringify(r.spatialReference||"none"));add(dF,"Min Scale",r.minScale||"None");add(dF,"Max Scale",r.maxScale||"None");aSL(dF,"Initial Extent",r.initialExtent);aSL(dF,"Full Extent",r.fullExtent);add(dF,"Units",r.units.replace("esri",""));aSL(dF,"Document Info",r.documentInfo);add(dF,"Max Record Count",r.maxRecordCount);tags[data.i].parentNode.appendChild(ul);ul.appendChild(dF);if(f.length){queryMe(f);}});}for(i=0;iHover over a Map Service link to view it.

    ": ""); 23 | d.body.appendChild(node); 24 | require(["esri/map", "esri/request", "dojo/query", "dojo/domReady!"], function (Map, esriRequest, dojoQuery) { 25 | var map = new Map("map"); 26 | function addFeatureServiceLayer(data, u2) { 27 | if (data.layers && data.layers.length) { 28 | require(["esri/layers/FeatureLayer", "dojo/_base/array"], function (FeatureLayer, arrayUtils) { 29 | arrayUtils.forEach(data.layers, function (layerData) { 30 | var layer = new FeatureLayer(u2.replace(/\/?$/, "/" + layerData.id), {mode: FeatureLayer.MODE_SNAPSHOT, outFields: ["*"]}); 31 | map.addLayer(layer); 32 | }); 33 | }); 34 | } 35 | } 36 | function addMapServiceLayer(data, u2) { 37 | if (data.singleFusedMapCache) { 38 | require(["esri/layers/ArcGISTiledMapServiceLayer"], function (Tiled) { 39 | var layer = new Tiled(u2); 40 | map.addLayer(layer); 41 | }); 42 | } else { 43 | require(["esri/layers/ArcGISDynamicMapServiceLayer"], function (Dynamic) { 44 | var layer = new Dynamic(u2); 45 | map.addLayer(layer); 46 | }); 47 | } 48 | } 49 | function resetMap() { 50 | if (map.graphicsLayerIds.length + map.layerIds.length > 0) { 51 | map.destroy(); 52 | map = new Map("map"); 53 | } 54 | } 55 | if (single) { 56 | addMapServiceLayer(url); 57 | } else { 58 | dojoQuery("a[href$=MapServer]").on("mouseover", function (evt) { 59 | var u3 = evt.currentTarget.href; 60 | resetMap(); 61 | esriRequest({ 62 | url: u3, 63 | handleAs: "json", 64 | content: {f: "json"} 65 | }).then( function (data) { 66 | addMapServiceLayer(data, u3); 67 | }, function (err) { 68 | console.error(err); 69 | }); 70 | }); 71 | dojoQuery("a[href$=FeatureServer]").on("mouseover", function (evt) { 72 | var u3 = evt.currentTarget.href; 73 | resetMap(); 74 | esriRequest({ 75 | url: u3, 76 | handleAs: "json", 77 | content: {f: "json"} 78 | }).then(function (data) { 79 | addFeatureServiceLayer(data, u3); 80 | }, function (err) { 81 | console.error(err); 82 | }); 83 | }); 84 | } 85 | }); 86 | } 87 | test = [].some.call(d.getElementsByTagName("script"), function (scr) { 88 | return scr.src === js; 89 | }); 90 | 91 | if (test) { 92 | loadMap(); 93 | } else { 94 | style1 = loadElement("link", { 95 | rel: "stylesheet", 96 | type: "text/css", 97 | href: css 98 | }); 99 | d.head.appendChild(style1); 100 | scr1 = loadElement("script", { 101 | type: "text/javascript" 102 | }); 103 | scr1.onload = loadMap; 104 | scr1.setAttribute("src", js); 105 | d.body.appendChild(scr1); 106 | } 107 | }()); 108 | -------------------------------------------------------------------------------- /MapViewer/MapViewer.min.js: -------------------------------------------------------------------------------- 1 | (function(){var h=document,a=window.location.href.replace(window.location.search,""),k=/(map|feature)server\/?$/i.test(a),g=false,b="//js.arcgis.com/3.15compact",f="//js.arcgis.com/3.15/esri/css/esri.css",j,i;function c(d,m){var n=h.createElement(d),l;for(l in m){n.setAttribute(l,m[l])}return n}function e(){var d=c("div",{style:"position:fixed;top:0;right:0;border:1px solid grey;z-index:10;padding:8px;background:#fff;"});d.innerHTML="
    "+(!k?"

    Hover over a Map Service link to view it.

    ":"");h.body.appendChild(d);require(["esri/map","esri/request","dojo/query","dojo/domReady!"],function(m,q,o){var p=new m("map");function l(t,s){if(t.layers&&t.layers.length){require(["esri/layers/FeatureLayer","dojo/_base/array"],function(v,u){u.forEach(t.layers,function(x){var w=new v(s.replace(/\/?$/,"/"+x.id),{mode:v.MODE_SNAPSHOT,outFields:["*"]});p.addLayer(w)})})}}function r(t,s){if(t.singleFusedMapCache){require(["esri/layers/ArcGISTiledMapServiceLayer"],function(u){var v=new u(s);p.addLayer(v)})}else{require(["esri/layers/ArcGISDynamicMapServiceLayer"],function(v){var u=new v(s);p.addLayer(u)})}}function n(){if(p.graphicsLayerIds.length+p.layerIds.length>0){p.destroy();p=new m("map")}}if(k){r(a)}else{o("a[href$=MapServer]").on("mouseover",function(s){var t=s.currentTarget.href;n();q({url:t,handleAs:"json",content:{f:"json"}}).then(function(u){r(u,t)},function(u){console.error(u)})});o("a[href$=FeatureServer]").on("mouseover",function(s){var t=s.currentTarget.href;n();q({url:t,handleAs:"json",content:{f:"json"}}).then(function(u){l(u,t)},function(u){console.error(u)})})}})}g=[].some.call(h.getElementsByTagName("script"),function(d){return d.src===b});if(g){e()}else{j=c("link",{rel:"stylesheet",type:"text/css",href:f});h.head.appendChild(j);i=c("script",{type:"text/javascript"});i.onload=e;i.setAttribute("src",b);h.body.appendChild(i)}}()); -------------------------------------------------------------------------------- /MapViewer/README.md: -------------------------------------------------------------------------------- 1 | # Map Service Viewer (MapViewer.js) - ESRI REST Diagnostics 2 | 3 | A JavaScript bookmarklet for viewing a Map or Feature Service from the REST Service. 4 | 5 | ## Features 6 | 7 | This bookmarklet loads an ArcGIS JavaScript API based map on the REST Service page, then loads a map with whatever map or feature service you specify. If you are on a map service level, it will automatically load the map service at the top of the page. If you are on a folder level with multiple services, you can hover your mouse over the links to the map or feature service to view it in the viewer. 8 | 9 | ## Instructions 10 | 11 | ### Installation 12 | 13 | Installation on the browser is as simple as adding a bookmark. From the [ESRI Rest Diagnostics](http://raykendo.github.io/ESRI_REST_Diagnostics/) page... 14 | 15 | - Chrome: drag the anchor link to your browser toolbar. 16 | - Firefox: right-click on the link and select "Bookmark this link". 17 | - IE: right-click on the link and select "Add to Favorites". 18 | - Safari: untested. 19 | - Opera: drag the anchor link to your browser toolbar. 20 | 21 | ### Basic Use 22 | 23 | In the browser, navigate to the ArcGIS Server REST Service endpoint. You can either view multiple map services from the folder level, or a single map service if you are looking at the map service endpoint. 24 | 25 | ## Requirements 26 | 27 | - Desktop browser (IE8+, Chrome, Firefox) 28 | - Security settings that support bookmarklets. 29 | - Access to an ArcGIS Server REST endpoint in browser. 30 | 31 | ## Resources 32 | 33 | [ESRI JavaScript API](https://developers.arcgis.com/javascript/index.html) 34 | 35 | ## Contributing 36 | 37 | Anyone is welcome to contribute to this project. 38 | 39 | ## Licensing 40 | 41 | This is currently licensed under the MIT Licensing ([See License here](https://github.com/raykendo/ESRI_REST_Diagnostics/blob/master/LICENSE)). 42 | -------------------------------------------------------------------------------- /PrintTaskMadeEasy/PrintTaskMadeEasy.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | "use strict"; 3 | var url = window.location.href.split("?")[0], 4 | d = document, 5 | urlTest = /(execute|submitjob)\/?$/ig; 6 | // ajax function from https://gist.github.com/Xeoncross/7663273 7 | function ajax(u, callback, data, x) { 8 | try { 9 | x = new(window.XMLHttpRequest || ActiveXObject)("MSXML2.XMLHTTP.3.0"); 10 | x.open(data ? "POST" : "GET", u, 1); 11 | x.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 12 | x.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 13 | x.onreadystatechange = function () { 14 | x.readyState > 3 && callback && callback(JSON.parse(x.responseText), x); 15 | }; 16 | x.send(data); 17 | } catch (e) { 18 | window.console && console.log(e); 19 | } 20 | } 21 | function loadElement (tag, attributes, text) { 22 | var el = d.createElement(tag), a; 23 | for (a in attributes) { 24 | el.setAttribute(a, attributes[a]); 25 | } 26 | if (text) { 27 | el.innerHTML = text; 28 | } 29 | return el; 30 | } 31 | function swapInChoices(parameters, nodes) { 32 | parameters.forEach(function (param) { 33 | if (!param.choiceList) { 34 | return; 35 | } 36 | console.log("Parameter...", param); 37 | var select = loadElement("select", { 38 | "name": param.name 39 | }); 40 | param.choiceList.forEach(function(choice) { 41 | var option = loadElement("option", { 42 | value: choice 43 | }, choice); 44 | select.appendChild(option); 45 | }); 46 | select.value = param.defaultValue; 47 | var myNode = nodes.filter(function (node) { 48 | console.log(node.name); 49 | return node.name === param.name; 50 | })[0]; 51 | myNode.parentNode.replaceChild(select, myNode); 52 | }); 53 | } 54 | function toArray(item) { 55 | return [].map.call(item, function(i) {return i;}); 56 | } 57 | function dataRequested(response) { 58 | var myForm, blanks = [], b; 59 | if (!response.parameters) { 60 | alert("Could not find GP parameters for this task."); 61 | return; 62 | } 63 | try { 64 | myForm = d.getElementsByTagName("FORM")[0]; 65 | blanks = toArray(myForm.getElementsByTagName("TEXTAREA")); 66 | blanks = blanks.concat(toArray(myForm.getElementsByTagName("INPUT"))); 67 | swapInChoices(response.parameters, blanks); 68 | blanks.some(function (blank) { 69 | if (blank.name === "Web_Map_as_JSON") { 70 | blank.value = "{\"operationalLayers\":[],\"baseMap\":{\"baseMapLayers\":[{\"id\":\"defaultBasemap\",\"opacity\":1,\"visibility\":true,\"url\":\"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer\"}],\"title\":\"Topographic\"},\"exportOptions\":{\"dpi\":300,\"outputSize\":[1280,1024]}}"; 71 | } 72 | return blank.name === "Web_Map_as_JSON"; 73 | }) 74 | } catch (err) { 75 | console.error(err); 76 | alert("invalid form"); 77 | } 78 | } 79 | if (!urlTest.test(url)) { 80 | alert("Navigate to valid print task form.") 81 | } else { 82 | ajax(url.replace(urlTest, "") + "?f=json", dataRequested); 83 | } 84 | }()); 85 | -------------------------------------------------------------------------------- /PrintTaskMadeEasy/PrintTaskMadeEasy.min.js: -------------------------------------------------------------------------------- 1 | (function(){var a=window.location.href.split("?")[0],i=document,c=/(execute|submitjob)\/?$/ig;function g(j,m,k,d){try{d=new (window.XMLHttpRequest||ActiveXObject)("MSXML2.XMLHTTP.3.0");d.open(k?"POST":"GET",j,1);d.setRequestHeader("X-Requested-With","XMLHttpRequest");d.setRequestHeader("Content-type","application/x-www-form-urlencoded");d.onreadystatechange=function(){d.readyState>3&&m&&m(JSON.parse(d.responseText),d)};d.send(k)}catch(l){window.console&&console.log(l)}}function e(d,k,m){var l=i.createElement(d),j;for(j in k){l.setAttribute(j,k[j])}if(m){l.innerHTML=m}return l}function h(j,d){j.forEach(function(m){if(!m.choiceList){return}console.log("Parameter...",m);var k=e("select",{name:m.name});m.choiceList.forEach(function(n){var o=e("option",{value:n},n);k.appendChild(o)});k.value=m.defaultValue;var l=d.filter(function(n){console.log(n.name);return n.name===m.name})[0];l.parentNode.replaceChild(k,l)})}function b(d){return[].map.call(d,function(j){return j})}function f(j){var l,m=[],d;if(!j.parameters){alert("Could not find GP parameters for this task.");return}try{l=i.getElementsByTagName("FORM")[0];m=b(l.getElementsByTagName("TEXTAREA"));m=m.concat(b(l.getElementsByTagName("INPUT")));h(j.parameters,m);m.some(function(n){if(n.name==="Web_Map_as_JSON"){n.value="{\"operationalLayers\":[],\"baseMap\":{\"baseMapLayers\":[{\"id\":\"defaultBasemap\",\"opacity\":1,\"visibility\":true,\"url\":\"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer\"}],\"title\":\"Topographic\"},\"exportOptions\":{\"dpi\":300,\"outputSize\":[1280,1024]}}"}return n.name==="Web_Map_as_JSON"})}catch(k){console.error(k);alert("invalid form")}}if(!c.test(a)){alert("Navigate to valid print task form.")}else{g(a.replace(c,"")+"?f=json",f)}}()); 2 | -------------------------------------------------------------------------------- /PrintTaskMadeEasy/README.md: -------------------------------------------------------------------------------- 1 | # Print Task Made Easy (ESRI REST Diagnostics) (BETA) 2 | 3 | Modifies the HTML and contents of an ArcGIS Server *Export Web Map Task* to make it easier to fill out the form. 4 | ## Features 5 | 6 | This bookmarklet modifies the form for submitting an *Export Web Map Task*. It replaces form text blanks with select elements for fields with a choice list (like Format or Layout Template). It also provides a template Web Map as JSON to test a print service. 7 | 8 | 9 | ## Instructions 10 | 11 | ### Installation 12 | 13 | Installation on the browser is as simple as adding a bookmark. From the [ESRI Rest Diagnostics](http://raykendo.github.io/ESRI_REST_Diagnostics/) page... 14 | 15 | - Chrome: drag the anchor link to your browser toolbar. 16 | - Firefox: right-click on the link and select "Bookmark this link". 17 | - IE: right-click on the link and select "Add to Favorites". 18 | - Safari: untested. 19 | - Opera: drag the anchor link to your browser toolbar. 20 | 21 | ### Basic Use 22 | 23 | Navigate to an ArcGIS Server REST service endpoint in your browser. Find an *Export Web Map Task*, typically in the Utilities folder. At the bottom of the page, select either the "Execute Task" or "Submit Job" link to navigate to the *Export Web Map Task* form. From there, run the bookmark. 24 | 25 | *** 26 | 27 | ## Requirements 28 | 29 | - Desktop browser (IE10+, Chrome, Firefox) 30 | - Security settings that support bookmarklets. 31 | - Access to an ArcGIS Server REST endpoint in browser. 32 | 33 | ## Notes 34 | 35 | - Currently untested on Safari and Opera. Please give me feedback if you try it. 36 | - Not tested on mobile/tablet browsers, since I'm not sure how bookmarklets work with those. 37 | 38 | ## Contributing 39 | 40 | Anyone is welcome to contribute to this project. 41 | 42 | ## Licensing 43 | 44 | This is currently licensed under the MIT Licensing ([See License here](https://github.com/raykendo/ESRI_REST_Diagnostics/blob/master/LICENSE)). 45 | -------------------------------------------------------------------------------- /QueryHelper/QueryHelper.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var d = document, 3 | wl = window.location, 4 | url = wl.href.replace(wl.search, ""), 5 | qreg = /\/query\/?$/i, 6 | active; 7 | // ajax function from https://gist.github.com/Xeoncross/7663273 8 | function ajax(u, callback, data, x) { 9 | try { 10 | x = new(this.XMLHttpRequest || ActiveXObject)("MSXML2.XMLHTTP.3.0"); 11 | x.open(data ? "POST" : "GET", u, 1); 12 | x.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 13 | x.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 14 | x.onreadystatechange = function () { 15 | x.readyState > 3 && callback && callback(JSON.parse(x.responseText), x); 16 | }; 17 | x.send(data); 18 | } catch (e) { 19 | window.console && console.log(e); 20 | } 21 | } 22 | function listenAll(node, selector, evt, callback) { 23 | [].forEach.call(node.querySelectorAll(selector), function (el) { 24 | el[evt] = callback; 25 | }); 26 | } 27 | function build(fields) { 28 | var div = d.createElement("div"), 29 | listF = d.createElement("select"), 30 | listR = d.createElement("select"), 31 | btns = d.createElement("div"); 32 | div.setAttribute("style", "position:fixed;top:10%;right:0;width:35%;padding:5px;background:#fff;overflow:auto;"); 33 | div.innerHTML = "Query Builder
    "; 34 | 35 | var clear_button = d.createElement("button"); 36 | clear_button.textContent = "Clear"; 37 | clear_button.style = "float: right; margin: 10px -54px 0px 0px;"; 38 | clear_button.onclick = clearActive; 39 | div.appendChild(clear_button); 40 | 41 | d.body.appendChild(div); 42 | listF.setAttribute("size", "10"); 43 | listF.innerHTML = fields.map(function (field) { 44 | return [""].join(""); 45 | }).join(""); 46 | div.appendChild(listF); 47 | listR.setAttribute("size", "10"); 48 | div.appendChild(listR); 49 | listF.onchange = function () { 50 | var val = listF.value; 51 | ajax(url + "?where=1%3D1&returnGeometry=false&outFields=field&orderByFields=field&returnDistinctValues=true&f=json".replace(/field/g, val), function (res) { 52 | listR.innerHTML = [].map.call(res.features, function (feature) { 53 | feature_value = isNaN(feature.attributes[val] * 1) ? "'" + feature.attributes[val] + "'" : feature.attributes[val]; 54 | feature_text = feature.attributes[val]; 55 | return [""].join(""); 56 | }); 57 | }); 58 | }; 59 | btns.innerHTML = [" = ", " <> ", " LIKE ", " > ", " >= ", " AND ", " < ", " <= ", " OR ", "_", "%", "()", "NOT ", " IS ", "*", "''", " IN ", ", " ].map(function (txt) { 60 | return [""].join(""); 61 | }); 62 | div.appendChild(btns); 63 | return div; 64 | } 65 | function clearActive() { 66 | if (active !== undefined) 67 | { 68 | active.value = ""; 69 | } 70 | } 71 | function setActive(value) { 72 | if (active !== undefined) { 73 | // get cursor position 74 | var oldVal = active.value.substring(0), 75 | iCaretPos = oldVal.length; 76 | active.focus(); 77 | if (d.selection) { 78 | var oSel = d.selection.createRange(); 79 | oSel.moveStart("character", -active.value.length); 80 | iCaretPos = oSel.text.length; 81 | } else if ("selectionStart" in active) { 82 | iCaretPos = active.selectionStart; 83 | } 84 | // insert clicked text 85 | active.value = oldVal.substring(0, iCaretPos) + value + oldVal.substring(iCaretPos); 86 | 87 | // reset cursor position 88 | iCaretPos += value.length - (["()", "''"].indexOf(value) > -1); 89 | if (active.createTextRange) { 90 | var range = active.createTextRange(); 91 | range.move("character", iCaretPos); 92 | range.select(); 93 | } else if ("selectionStart" in active) { 94 | active.setSelectionRange(iCaretPos, iCaretPos); 95 | } 96 | } 97 | } 98 | function onLoad(response) { 99 | var node = build(response.fields); 100 | listenAll(node, "select", "ondblclick", function (evt) { 101 | setActive(evt.currentTarget.value); 102 | }); 103 | listenAll(node, "button.sql", "onclick", function (evt) { 104 | setActive(evt.currentTarget.name); 105 | }); 106 | } 107 | // set active blank when clicking on the controls. 108 | listenAll(d, "input[type=text], textarea", "onblur", function () { active = this; }); 109 | if (qreg.test(url)) { 110 | ajax(url.replace(qreg, "") + "?f=json", onLoad); 111 | } else { 112 | if (!/(map|feature)server\/\d+\/?$/i.test(url)) { 113 | alert("Go to the query page to use this tool."); 114 | } else { 115 | alert("Pick a valid layer"); 116 | } 117 | } 118 | }()); -------------------------------------------------------------------------------- /QueryHelper/QueryHelper.min.js: -------------------------------------------------------------------------------- 1 | (function(){var f=document,k=window.location,b=k.href.replace(k.search,""),h=/\/query\/?$/i,e;function i(l,o,m,d){try{d=new (this.XMLHttpRequest||ActiveXObject)("MSXML2.XMLHTTP.3.0");d.open(m?"POST":"GET",l,1);d.setRequestHeader("X-Requested-With","XMLHttpRequest");d.setRequestHeader("Content-type","application/x-www-form-urlencoded");d.onreadystatechange=function(){d.readyState>3&&o&&o(JSON.parse(d.responseText),d)};d.send(m)}catch(n){window.console&&console.log(n)}}function c(m,d,l,n){[].forEach.call(m.querySelectorAll(d),function(o){o[l]=n})}function j(l){var o=f.createElement("div"),m=f.createElement("select"),d=f.createElement("select"),n=f.createElement("div");o.setAttribute("style","position:fixed;top:10%;right:0;width:35%;padding:5px;background:#fff;overflow:auto;");o.innerHTML="Query Builder
    ";f.body.appendChild(o);m.setAttribute("size","10");m.innerHTML=l.map(function(p){return[""].join("")}).join("");o.appendChild(m);d.setAttribute("size","10");o.appendChild(d);m.onchange=function(){var p=m.value;i(b+"?where=1%3D1&returnGeometry=false&outFields=field&orderByFields=field&returnDistinctValues=true&f=json".replace(/field/g,p),function(q){d.innerHTML=[].map.call(q.features,function(r){return[""].join("")})})};n.innerHTML=[" = "," <> "," LIKE "," > "," >= "," AND "," < "," <= "," OR ","_","%","()","NOT "," IS ","*","''"," IN ",", "].map(function(p){return[""].join("")});o.appendChild(n);return o}function a(n){var m=e.value.substring(0),o=m.length;e.focus();if(f.selection){var d=f.selection.createRange();d.moveStart("character",-e.value.length);o=d.text.length}else{if("selectionStart" in e){o=e.selectionStart}}e.value=m.substring(0,o)+n+m.substring(o);o+=n.length-(["()",decodeURIComponent("%27%27")].indexOf(n)>-1);if(e.createTextRange){var l=e.createTextRange();l.move("character",o);l.select()}else{if("selectionStart" in e){e.setSelectionRange(o,o)}}}function g(d){var l=j(d.fields);c(l,"select","onclick",function(m){a(m.currentTarget.value)});c(l,"button.sql","onclick",function(m){a(m.currentTarget.name)})}c(f,"input[type=text], textarea","onblur",function(){e=this});if(h.test(b)){i(b.replace(h,"")+"?f=json",g)}else{if(!/(map|feature)server\/\d+\/?$/i.test(b)){alert("Go to the query page to use this tool.")}else{alert("Pick a valid layer")}}}()); 2 | -------------------------------------------------------------------------------- /QueryHelper/README.md: -------------------------------------------------------------------------------- 1 | # "Select By Attributes" Query Helper (ESRI REST Diagnostics) 2 | 3 | On the ArcGIS Server REST Query page for a layer, this bookmarklet presents the fields and SQL keywords in a useful form on the side of the page. 4 | 5 | ## Features 6 | 7 | The bookmarklet renders a control on the side of the page that lists field names, values, and SQL keywords on the side of an ArcGIS Server REST Service layer query page. As you select field names, it retrieves a list of valid values and populates the second selection list. 8 | 9 | ## Instructions 10 | 11 | ### Installation 12 | 13 | Installation on the browser is as simple as adding a bookmark. From the [ESRI Rest Diagnostics](http://raykendo.github.io/ESRI_REST_Diagnostics/) page... 14 | 15 | - Chrome: drag the anchor link to your browser toolbar. 16 | - Firefox: right-click on the link and select "Bookmark this link". 17 | - IE: right-click on the link and select "Add to Favorites". 18 | - Safari: untested. 19 | - Opera: drag the anchor link to your browser toolbar. 20 | 21 | ### Basic Use 22 | 23 | Navigate to an ArcGIS Server REST service endpoint in your browser. Drill down to a Map Service or a Feature Service layer, [like this US Census State layer](http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3/query). Call the bookmarklet from your bookmark bar, and let it run. 24 | 25 | The bookmarklet will show a form in the upper right hand corner that lists the field names by alias, as well as SQL keywords used in queries. Selecting a field from the list will populate whatever text blank you had selected previously with the field name. It will also request a list of valid results, and fill them in a second selection list. Clicking on any list or button will fill the last text blank you selected with field names, results, and SQL keywords. 26 | 27 | ## Requirements 28 | 29 | - Desktop browser (IE10+, Chrome, Firefox) 30 | - Security settings that support bookmarklets. 31 | - Access to an ArcGIS Server REST endpoint in browser. 32 | 33 | ## Notes 34 | 35 | - Currently untested on Safari. Please give me feedback if you try it. 36 | - Not tested on mobile/tablet browsers, since I'm not sure how bookmarklets work with those. 37 | 38 | ## Contributing 39 | 40 | Anyone is welcome to contribute to this project. 41 | 42 | ## Licensing 43 | 44 | This is currently licensed under the MIT Licensing ([See License here](https://github.com/raykendo/ESRI_REST_Diagnostics/blob/master/LICENSE)). 45 | -------------------------------------------------------------------------------- /QuickQueryHelpers/AllNoGeo_QueryHelper.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | "use strict"; 3 | var url = window.location.href.split("?")[0]; 4 | 5 | // set active blank when clicking on the controls. 6 | function elementsToArray(tag) { 7 | return [].map.call(document.getElementsByTagName(tag), function (item) { return item; }); 8 | } 9 | function getBlanks() { 10 | return elementsToArray("INPUT").concat(elementsToArray("TEXTAREA")); 11 | } 12 | function fillBlanks(blanks) { 13 | var fieldValues = { 14 | where: "1=1", 15 | outFields: "*", 16 | returnGeometry: "false" 17 | }; 18 | blanks.forEach(function (blank) { 19 | if (fieldValues.hasOwnProperty(blank.name)) { 20 | if (blank.type && blank.type === "radio" && fieldValues[blank.name] === blank.value) { 21 | blank.checked = true; 22 | } else { 23 | blank.value = fieldValues[blank.name]; 24 | } 25 | } 26 | }); 27 | } 28 | if (/\/query\/?$/i.test(url)) { 29 | fillBlanks(getBlanks()); 30 | } else { 31 | if (!/(map|feature)server\/\d+\/?$/i.test(url)) { 32 | alert("Go to the query page to use this tool."); 33 | } else { 34 | alert("Pick a valid layer"); 35 | } 36 | } 37 | }()); 38 | -------------------------------------------------------------------------------- /QuickQueryHelpers/AllNoGeo_QueryHelper.min.js: -------------------------------------------------------------------------------- 1 | (function(){var a=window.location.href.split("?")[0];function d(e){return[].map.call(document.getElementsByTagName(e),function(f){return f})}function b(){return d("INPUT").concat(d("TEXTAREA"))}function c(f){var e={where:"1=1",outFields:"*",returnGeometry:"false"};f.forEach(function(g){if(e.hasOwnProperty(g.name)){if(g.type&&g.type==="radio"&&e[g.name]===g.value){g.checked=true}else{g.value=e[g.name]}}})}if(/\/query\/?$/i.test(a)){c(b())}else{if(!/(map|feature)server\/\d+\/?$/i.test(a)){alert("Go to the query page to use this tool.")}else{alert("Pick a valid layer")}}}()); -------------------------------------------------------------------------------- /QuickQueryHelpers/CountThemUp_QueryHelper.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | "use strict"; 3 | var url = window.location.href.split("?")[0]; 4 | 5 | // set active blank when clicking on the controls. 6 | function elementsToArray(tag) { 7 | return [].map.call(document.getElementsByTagName(tag), function (item) { return item; }); 8 | } 9 | function getBlanks() { 10 | return elementsToArray("INPUT").concat(elementsToArray("TEXTAREA")); 11 | } 12 | function fillBlanks(blanks) { 13 | var fieldValues = { 14 | "where": "1=1", 15 | returnCountOnly: "true" 16 | }; 17 | blanks.forEach(function (blank) { 18 | if (fieldValues.hasOwnProperty(blank.name)) { 19 | if (blank.type && blank.type === "radio" && fieldValues[blank.name] === blank.value) { 20 | blank.checked = true; 21 | } else { 22 | blank.value = fieldValues[blank.name]; 23 | } 24 | } 25 | }); 26 | } 27 | if (/\/query\/?$/i.test(url)) { 28 | fillBlanks(getBlanks()); 29 | } else { 30 | if (!/(map|feature)server\/\d+\/?$/i.test(url)) { 31 | alert("Go to the query page to use this tool."); 32 | } else { 33 | alert("Pick a valid layer"); 34 | } 35 | } 36 | }()); 37 | -------------------------------------------------------------------------------- /QuickQueryHelpers/CountThemUp_QueryHelper.min.js: -------------------------------------------------------------------------------- 1 | (function(){var a=window.location.href.split("?")[0];function d(e){return[].map.call(document.getElementsByTagName(e),function(f){return f})}function b(){return d("INPUT").concat(d("TEXTAREA"))}function c(f){var e={where:"1=1",returnCountOnly:"true"};f.forEach(function(g){if(e.hasOwnProperty(g.name)){if(g.type&&g.type==="radio"&&e[g.name]===g.value){g.checked=true}else{g.value=e[g.name]}}})}if(/\/query\/?$/i.test(a)){c(b())}else{if(!/(map|feature)server\/\d+\/?$/i.test(a)){alert("Go to the query page to use this tool.")}else{alert("Pick a valid layer")}}}()); -------------------------------------------------------------------------------- /QuickQueryHelpers/GiveMeAll_QueryHelper.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | "use strict"; 3 | var url = window.location.href.split("?")[0]; 4 | 5 | // set active blank when clicking on the controls. 6 | function elementsToArray(tag) { 7 | return [].map.call(document.getElementsByTagName(tag), function (item) { return item; }); 8 | } 9 | function getBlanks() { 10 | return elementsToArray("INPUT").concat(elementsToArray("TEXTAREA")); 11 | } 12 | function fillBlanks(blanks) { 13 | var fieldValues = { 14 | where: "1=1", 15 | outFields: "*", 16 | returnGeometry: "true" 17 | }; 18 | blanks.forEach(function (blank) { 19 | if (fieldValues.hasOwnProperty(blank.name)) { 20 | if (blank.type && blank.type === "radio" && fieldValues[blank.name] === blank.value) { 21 | blank.checked = true; 22 | } else { 23 | blank.value = fieldValues[blank.name]; 24 | } 25 | } 26 | }); 27 | } 28 | if (/\/query\/?$/i.test(url)) { 29 | fillBlanks(getBlanks()); 30 | } else { 31 | if (!/(map|feature)server\/\d+\/?$/i.test(url)) { 32 | alert("Go to the query page to use this tool."); 33 | } else { 34 | alert("Pick a valid layer"); 35 | } 36 | } 37 | }()); 38 | -------------------------------------------------------------------------------- /QuickQueryHelpers/GiveMeAll_QueryHelper.min.js: -------------------------------------------------------------------------------- 1 | (function(){var a=window.location.href.split("?")[0];function d(e){return[].map.call(document.getElementsByTagName(e),function(f){return f})}function b(){return d("INPUT").concat(d("TEXTAREA"))}function c(f){var e={where:"1=1",outFields:"*",returnGeometry:"true"};f.forEach(function(g){if(e.hasOwnProperty(g.name)){if(g.type&&g.type==="radio"&&e[g.name]===g.value){g.checked=true}else{g.value=e[g.name]}}})}if(/\/query\/?$/i.test(a)){c(b())}else{if(!/(map|feature)server\/\d+\/?$/i.test(a)){alert("Go to the query page to use this tool.")}else{alert("Pick a valid layer")}}}()); -------------------------------------------------------------------------------- /QuickQueryHelpers/README.md: -------------------------------------------------------------------------------- 1 | # Quick Query Helpers 2 | 3 | On the ArcGIS Server REST Query page for a layer, these bookmarklets will fill in the query pages with default values. 4 | 5 | ## Features 6 | 7 | These bookmarklets supply simple default values for fields in the ArcGIS Server REST Query page. Each Bookmarklet affects the following fields. 8 | 9 | - *Give Me All* 10 | - where: 1=1 11 | - outFields: * 12 | - returnGeometry: true 13 | - *Count Them Up* 14 | - where: 1=1 15 | - returnCountOnly: true 16 | - *Everything But Geometry* 17 | - where: 1=1 18 | - outFields: * 19 | - returnGeometry: false 20 | - *Select Distinct* 21 | - where: 1=1 22 | - returnGeometry: false 23 | - outFields: value selected from a dropdown selection 24 | - returnDistinctValues: true 25 | 26 | ## Instructions 27 | 28 | ### Installation 29 | 30 | Installation on the browser is as simple as adding a bookmark. From the [ESRI Rest Diagnostics](http://raykendo.github.io/ESRI_REST_Diagnostics/) page... 31 | 32 | - Chrome: drag the anchor link to your browser toolbar. 33 | - Firefox: right-click on the link and select "Bookmark this link". 34 | - IE: right-click on the link and select "Add to Favorites". 35 | - Safari: untested. 36 | - Opera: drag the anchor link to your browser toolbar. 37 | 38 | ### Basic Use 39 | 40 | Navigate to an ArcGIS Server REST service endpoint in your browser. Drill down to a Map Service or a Feature Service layer, [like this US Census State layer](http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3/query). Call the bookmarklet from your bookmark bar, and let it run. 41 | 42 | The bookmarklet will show a form in the upper right hand corner that lists the field names by alias, as well as SQL keywords used in queries. Selecting a field from the list will populate whatever text blank you had selected previously with the field name. It will also request a list of valid results, and fill them in a second selection list. Clicking on any list or button will fill the last text blank you selected with field names, results, and SQL keywords. 43 | 44 | ## Requirements 45 | 46 | - Desktop browser (IE10+, Chrome, Firefox) 47 | - Security settings that support bookmarklets. 48 | - Access to an ArcGIS Server REST endpoint in browser. 49 | 50 | ## Notes 51 | 52 | - Currently untested on Safari. Please give me feedback if you try it. 53 | - Not tested on mobile/tablet browsers, since I'm not sure how bookmarklets work with those. 54 | 55 | ## Contributing 56 | 57 | Anyone is welcome to contribute to this project. 58 | 59 | ## Licensing 60 | 61 | This is currently licensed under the MIT Licensing ([See License here](https://github.com/raykendo/ESRI_REST_Diagnostics/blob/master/LICENSE)). 62 | -------------------------------------------------------------------------------- /QuickQueryHelpers/SelectDistinct_QueryHelper.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | "use strict"; 3 | var url = window.location.href.split("?")[0], 4 | qreg = /\/query\/?$/i; 5 | 6 | // ajax function from https://gist.github.com/Xeoncross/7663273 7 | function ajax(u, callback, data, x) { 8 | try { 9 | x = new(window.XMLHttpRequest || ActiveXObject)("MSXML2.XMLHTTP.3.0"); 10 | x.open(data ? "POST" : "GET", u, 1); 11 | x.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 12 | x.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 13 | x.onreadystatechange = function () { 14 | x.readyState > 3 && callback && callback(JSON.parse(x.responseText), x); 15 | }; 16 | x.send(data); 17 | } catch (e) { 18 | window.console && console.log(e); 19 | } 20 | } 21 | function loadElement (tag, attributes, text) { 22 | var el = document.createElement(tag), a; 23 | for (a in attributes) { 24 | el.setAttribute(a, attributes[a]); 25 | } 26 | if (text) { 27 | el.innerHTML = text; 28 | } 29 | return el; 30 | } 31 | function swapInFields(fields, node) { 32 | var select = loadElement("select", { 33 | "name": node.name 34 | }); 35 | fields.forEach(function(field) { 36 | var option = loadElement("option", { 37 | value: field.name 38 | }, field.alias + " (" + field.name + ")"); 39 | select.appendChild(option); 40 | }); 41 | select.value = fields[0].name; 42 | node.parentNode.replaceChild(select, node); 43 | } 44 | // set active blank when clicking on the controls. 45 | function elementsToArray(tag) { 46 | return [].map.call(document.getElementsByTagName(tag), function (item) { return item; }); 47 | } 48 | function getBlanks() { 49 | return elementsToArray("INPUT").concat(elementsToArray("TEXTAREA")); 50 | } 51 | function fillBlanks(blanks) { 52 | var fieldValues = { 53 | where: "1=1", 54 | returnDistinctValues: "true", 55 | returnGeometry: "false" 56 | }; 57 | blanks.forEach(function (blank) { 58 | if (fieldValues.hasOwnProperty(blank.name)) { 59 | if (blank.type && blank.type === "radio" && fieldValues[blank.name] === blank.value) { 60 | blank.checked = true; 61 | } else { 62 | blank.value = fieldValues[blank.name]; 63 | } 64 | } else if (blank.name === "outFields") { 65 | ajax(url.replace(qreg, "?f=json"), function (response) { 66 | swapInFields(response.fields.filter(function (field) { 67 | return field.type.substr(13).toLowerCase() !== "geometry"; 68 | }), blank); 69 | }) 70 | } 71 | }); 72 | } 73 | if (qreg.test(url)) { 74 | fillBlanks(getBlanks()); 75 | } else { 76 | if (!/(map|feature)server\/\d+\/?$/i.test(url)) { 77 | alert("Go to the query page to use this tool."); 78 | } else { 79 | alert("Pick a valid layer"); 80 | } 81 | } 82 | }()); 83 | -------------------------------------------------------------------------------- /QuickQueryHelpers/SelectDistinct_QueryHelper.min.js: -------------------------------------------------------------------------------- 1 | (function(){var a=window.location.href.split("?")[0],g=/\/query\/?$/i;function f(j,m,k,i){try{i=new (window.XMLHttpRequest||ActiveXObject)("MSXML2.XMLHTTP.3.0");i.open(k?"POST":"GET",j,1);i.setRequestHeader("X-Requested-With","XMLHttpRequest");i.setRequestHeader("Content-type","application/x-www-form-urlencoded");i.onreadystatechange=function(){i.readyState>3&&m&&m(JSON.parse(i.responseText),i)};i.send(k)}catch(l){window.console&&console.log(l)}}function c(i,k,m){var l=document.createElement(i),j;for(j in k){l.setAttribute(j,k[j])}if(m){l.innerHTML=m}return l}function h(j,k){var i=c("select",{name:k.name});j.forEach(function(m){var l=c("option",{value:m.name},m.alias+" ("+m.name+")");i.appendChild(l)});i.value=j[0].name;k.parentNode.replaceChild(i,k)}function e(i){return[].map.call(document.getElementsByTagName(i),function(j){return j})}function b(){return e("INPUT").concat(e("TEXTAREA"))}function d(j){var i={where:"1=1",returnDistinctValues:"true",returnGeometry:"false"};j.forEach(function(k){if(i.hasOwnProperty(k.name)){if(k.type&&k.type==="radio"&&i[k.name]===k.value){k.checked=true}else{k.value=i[k.name]}}else{if(k.name==="outFields"){f(a.replace(g,"?f=json"),function(l){h(l.fields.filter(function(m){return m.type.substr(13).toLowerCase()!=="geometry"}),k)})}}})}if(g.test(a)){d(b())}else{if(!/(map|feature)server\/\d+\/?$/i.test(a)){alert("Go to the query page to use this tool.")}else{alert("Pick a valid layer")}}}()); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESRI REST Diagnostics 2 | 3 | A list of JavaScript bookmarklets that can be used to test ArcGIS Server Map Services through the browser. 4 | 5 | ## Features 6 | 7 | The bookmarklets provided add extra information to the ArcGIS Server REST endpoint pages. They work by collecting the underlying data and adding the results to the current HTML REST Service page. Some of features include: 8 | 9 | - Folder level: 10 | - [Extract Map Service data for each Map and Feature Service in the folder.](https://github.com/raykendo/ESRI_REST_Diagnostics/tree/master/MapServiceData) 11 | - [Compare Spatial References of all Map and Feature Services in a folder.](https://github.com/raykendo/ESRI_REST_Diagnostics/tree/master/SpatialRefCompare) 12 | - [View Maps in a map service.](https://github.com/raykendo/ESRI_REST_Diagnostics/tree/master/MapViewer) 13 | - Map Service level: 14 | - [Extract Layer data for each layer in the service.](https://github.com/raykendo/ESRI_REST_Diagnostics/tree/master/MapLayerData) 15 | - [Get counts of features and shapes for each layer in the service.](https://github.com/raykendo/ESRI_REST_Diagnostics/tree/master/MapLayerCount) 16 | - [Test whether tiles have been built at different levels of detail in a tiled map service.](https://github.com/raykendo/ESRI_REST_Diagnostics/tree/master/TileTester) 17 | - [View the service on a map.](https://github.com/raykendo/ESRI_REST_Diagnostics/tree/master/MapViewer) 18 | - Map Service Layer level 19 | - [Test each field for number of non-empty results.](https://github.com/raykendo/ESRI_REST_Diagnostics/tree/master/FieldTester) 20 | - [Test each field for content and see how fast the results return.](https://github.com/raykendo/ESRI_REST_Diagnostics/tree/master/FieldTester) 21 | - [Test each field with a coded value domain to see how many features have each coded value.](https://github.com/raykendo/ESRI_REST_Diagnostics/tree/master/DomainDataCounter) 22 | - Miscellaneous 23 | - [Search REST Services for specific field or text string](https://github.com/raykendo/ESRI_REST_Diagnostics/tree/master/RestSearch) 24 | - [Use a "Select By Attributes" like query helper to create Queries](https://github.com/raykendo/ESRI_REST_Diagnostics/tree/master/QueryHelper) 25 | - [Adding ArcGIS REST API compliant geometry json to queries, based on a map of the map service.](https://github.com/raykendo/ESRI_REST_Diagnostics/tree/master/GeometryHelper) 26 | 27 | More features will be made available on request. 28 | 29 | ## Instructions 30 | 31 | ### Installation 32 | 33 | Installation on the browser is as simple as adding a bookmark. From the [ESRI Rest Diagnostics](http://raykendo.github.io/ESRI_REST_Diagnostics/) page... 34 | 35 | - Chrome: drag the anchor link to your browser toolbar. ![Install to Chrome illustration](images/Install_Chrome.gif "Installing bookmarklets on Chrome") 36 | - Firefox: right-click on the link and select "Bookmark this link". ![Install to Firefox illustration](images/Install_Firefox.gif "Installing bookmarklets on Firefox") 37 | - IE: right-click on the link and select "Add to Favorites". ![Install to Internet Explorer illustration](images/Install_IE.gif "Installing bookmarklets on Internet Explorer") 38 | - Safari: untested. 39 | - Opera: drag the anchor link to your browser toolbar. ![Install to Opera illustration](images/Install_Opera.gif "Installing bookmarklets on Opera") 40 | 41 | ### Basic Use 42 | 43 | Each tool as its own basic use policy. They all involve navigating your web browser to the map service REST endpoint. From there, select the proper bookmark from the bookmark list. 44 | 45 | ## Requirements 46 | 47 | - Desktop browser (IE8+, Chrome, Firefox) 48 | - Security settings that support bookmarklets. 49 | - Access to an ArcGIS Server REST endpoint in browser. 50 | - Some tools require access to [ArcGIS JavaScript API library](http://js.arcgis.com/3.15/). 51 | 52 | ## Resources 53 | 54 | [ArcGIS JavaScript API](https://developers.arcgis.com/javascript/index.html) 55 | 56 | ## Contributing 57 | 58 | Anyone is welcome to contribute to this project. 59 | 60 | ## Licensing 61 | 62 | This is currently licensed under the MIT Licensing ([See License here](https://github.com/raykendo/ESRI_REST_Diagnostics/blob/master/LICENSE)). 63 | -------------------------------------------------------------------------------- /RestSearch/README.md: -------------------------------------------------------------------------------- 1 | # ArcGIS REST Service Search (RestSearch.js) - ESRI REST Diagnostics 2 | 3 | A JavaScript bookmarklet for searching for properties in map services based on a string or numeric value. 4 | 5 | ## Features 6 | 7 | This bookmarklet queries the current and lower level REST Service endpoints to find a text value that matches the current search text. 8 | 9 | This bookmarklet searches through map service folders and names, field names and attributes, layer names, layer descriptions, copyright text, and other data. Results are provided in a list with links pointing to the resulting data. 10 | 11 | ## Instructions 12 | 13 | ### Installation 14 | 15 | Installation on the browser is as simple as adding a bookmark. From the [ESRI Rest Diagnostics](http://raykendo.github.io/ESRI_REST_Diagnostics/) page... 16 | 17 | - Chrome: drag the anchor link to your browser toolbar. 18 | - Firefox: right-click on the link and select "Bookmark this link". 19 | - IE: right-click on the link and select "Add to Favorites". 20 | - Safari: untested. 21 | - Opera: drag the anchor link to your browser toolbar. 22 | 23 | ### Basic Use 24 | 25 | In the browser, navigate to any ArcGIS Server REST Service endpoint. From there, select the REST Search bookmarklet from the bookmark list. When the search box appears in the upper right hand corner, enter the value you wish to search for, and click the "Search" button. Depending on your internet connection and the ArcGIS Server connection, searches may take a minute or two to complete. 26 | 27 | Once the list of possible results is generated, links to the resulting layers will be provided, as well as data about the map service name, property, and the matching result. Clicking on the link will navigate you to the result. 28 | 29 | Please Note: Once you navigate away from the page, the search results will be removed, and will have to be generated again. If you must keep the search results, even temporarily, it is recommended that you open the links in a new tab or window. 30 | 31 | ## Requirements 32 | 33 | - Desktop browser (IE8+, Chrome, Firefox) 34 | - Security settings that support bookmarklets. 35 | - Access to an ArcGIS Server REST endpoint in browser. 36 | 37 | ## Resources 38 | 39 | [ESRI JavaScript API](https://developers.arcgis.com/javascript/index.html) 40 | 41 | ## Contributing 42 | 43 | Anyone is welcome to contribute to this project. 44 | 45 | ## Licensing 46 | 47 | This is currently licensed under the MIT Licensing ([See License here](https://github.com/raykendo/ESRI_REST_Diagnostics/blob/master/LICENSE)). 48 | -------------------------------------------------------------------------------- /RestSearch/RestSearch.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var d = document, 3 | form = d.createElement("form"), 4 | txt = d.createElement("input"), 5 | btn = d.createElement("button"), 6 | resultList = d.createElement("ul"), 7 | locs, hits; 8 | 9 | // ajax function from https://gist.github.com/Xeoncross/7663273 10 | function ajax(u, callback, data, x) { 11 | try { 12 | x = new(this.XMLHttpRequest || ActiveXObject)("MSXML2.XMLHTTP.3.0"); 13 | x.open(data ? "POST" : "GET", u, 1); 14 | x.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 15 | x.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 16 | x.onreadystatechange = function () { 17 | x.readyState > 3 && callback && callback(JSON.parse(x.responseText), x); 18 | }; 19 | x.send(data); 20 | } catch (e) { 21 | window.console && console.log(e); 22 | } 23 | } 24 | // get values of dot.notated.parameters out of a JSON object 25 | // @param {string[]} fields - list of fields 26 | // @param {object} data - JSON object. 27 | function getFinalVal(fields, data) { 28 | var result = data.hasOwnProperty(fields[0]) ? data[fields[0]] : null; 29 | if (result != null && fields.length > 1) { 30 | if (result instanceof Array) { 31 | return result.map(function (item) { 32 | return getFinalVal(fields.slice(1), item); 33 | }); 34 | } 35 | return getFinalVal(fields.slice(1), result); 36 | } 37 | return result; 38 | } 39 | // displays a link to a map service REST endpoint with data that matches the search. 40 | // @param {string} field 41 | // @param {string} result 42 | // @param {string} url 43 | function printResult(field, result, url) { 44 | var li = d.createElement("li"), 45 | link = d.createElement("a"); 46 | link.setAttribute("href", url); 47 | link.innerHTML = [url.replace(/^\S*\/rest\/services\//i, ""), "=> ", field, ": ", result].join(""); 48 | li.appendChild(link); 49 | resultList.appendChild(li); 50 | } 51 | // test if the result matches the search. If so, increments the hit counter and displays the result. 52 | function checkAndPrint(myTest, field, result, url) { 53 | if (myTest(result)) { 54 | hits++; 55 | printResult(field, result, url); 56 | } 57 | } 58 | // collect values from the data, and send the data off for testing. 59 | function responseSearch(url, data, myTest) { 60 | var fieldList = ["name", "description", "displayField", "fields.name", "fields.alias", "mapName", "layers.name", "documentInfo.Title", "documentInfo.Comments", "documentInfo.Subject", "documentInfo.Category", "documentInfo.Keywords", "folders", "services.name", "services.type"]; 61 | fieldList.forEach(function (field) { 62 | var result = getFinalVal(field.split("."), data); 63 | if (result == null) { return; } 64 | if (result instanceof Array) { 65 | result.forEach(function (item) { 66 | checkAndPrint(myTest, field, item, url); 67 | }); 68 | } else { 69 | checkAndPrint(myTest, field, result, url); 70 | } 71 | }); 72 | } 73 | 74 | // returns a list of child folders for the current service. 75 | function subUrls(url, data) { 76 | var list = [], 77 | runners = { 78 | "folders": function (folder) { return [url, folder].join("/"); }, 79 | "services": function (service) { return [url, service.name.replace(/\w+\//ig, ""), service.type].join("/"); }, 80 | "layers": function (layer) { return [url, layer.id].join("/"); }, 81 | "tables": function (table) { return [url, table.id].join("/"); } 82 | }, r; 83 | for (r in runners) { 84 | if (data[r] && data[r].length) { 85 | list = list.concat(data[r].map(runners[r])); 86 | } 87 | } 88 | return list; 89 | } 90 | // given a list of urls and a testing function, requests data from the first url in the list, searches the JSON response, 91 | // and if there are more urls in the list, calls itself again. 92 | // @param {string[]} list - list of urls 93 | // @param {function} myTest - test to perform on the results to see if it matches. 94 | function queryMe(list, myTest) { 95 | if (!list.length) { return; } 96 | var url = list.shift(); 97 | ajax(url + "?f=json", 98 | function (data) { 99 | locs++; 100 | responseSearch(url, data, myTest); 101 | list = list.concat(subUrls(url, data)); 102 | if (list.length) { 103 | queryMe(list, myTest); 104 | } else { 105 | btn.removeAttribute("disabled"); 106 | btn.innerHTML = "Search"; 107 | var li = d.createElement("li"); 108 | li.innerHTML = ["Places Searched:",locs,"
    Results found",hits].join(" "); 109 | resultList.insertBefore(li, resultList.firstChild); 110 | } 111 | }); 112 | } 113 | // function called on mouse click, parses searches, sets up tests, and queries the current REST service. 114 | function onSubmit() { 115 | var searchFor, myTest; 116 | if (txt.value) { 117 | // clear the list 118 | while (resultList.childNodes.length) { 119 | resultList.removeChild(resultList.childNodes[0]); 120 | } 121 | btn.innerHTML = "Scanning"; 122 | btn.setAttribute("disabled", "disabled"); 123 | 124 | if (/^\d*\.?\d+$/.test(txt.value)) { 125 | searchFor = /\./.test(txt.value) ? parseFloat(txt.value) : parseInt(txt.value, 10); 126 | myTest = function (val) { return val === searchFor; }; 127 | } else { 128 | searchFor = new RegExp(txt.value, "i"); 129 | myTest = function (val) { return searchFor.test(val); }; 130 | } 131 | locs = 0; 132 | hits = 0; 133 | queryMe([window.location.href.replace(window.location.search, "")], myTest); 134 | } else { alert("Please enter a value"); } 135 | return false; 136 | } 137 | 138 | form.setAttribute("style", "position:fixed;top:5px;right:5px;width:300px;height:80%;overflow:auto;z-index:100;background:#fff;font-size:0.9em;"); 139 | txt.setAttribute("style", "width:75%"); 140 | form.appendChild(txt); 141 | btn.innerHTML = "Search"; 142 | btn.onclick = onSubmit; 143 | form.appendChild(btn); 144 | form.appendChild(resultList); 145 | d.body.appendChild(form); 146 | }()); -------------------------------------------------------------------------------- /RestSearch/RestSearch.min.js: -------------------------------------------------------------------------------- 1 | (function(){var l=document,b=l.createElement("form"),h=l.createElement("input"),c=l.createElement("button"),f=l.createElement("ul"),k,g;function m(q,t,r,d){try{d=new (this.XMLHttpRequest||ActiveXObject)("MSXML2.XMLHTTP.3.0");d.open(r?"POST":"GET",q,1);d.setRequestHeader("X-Requested-With","XMLHttpRequest");d.setRequestHeader("Content-type","application/x-www-form-urlencoded");d.onreadystatechange=function(){d.readyState>3&&t&&t(JSON.parse(d.responseText),d)};d.send(r)}catch(s){window.console&&console.log(s)}}function i(q,r){var d=r.hasOwnProperty(q[0])?r[q[0]]:null;if(d!=null&&q.length>1){if(d instanceof Array){return d.map(function(s){return i(q.slice(1),s)})}return i(q.slice(1),d)}return d}function e(t,q,r){var d=l.createElement("li"),s=l.createElement("a");s.setAttribute("href",r);s.innerHTML=[r.replace(/^\S*\/rest\/services\//i,""),"=> ",t,": ",q].join("");d.appendChild(s);f.appendChild(d)}function o(s,r,d,q){if(s(d)){g++;e(r,d,q)}}function a(q,r,s){var d=["name","description","displayField","fields.name","fields.alias","mapName","layers.name","documentInfo.Title","documentInfo.Comments","documentInfo.Subject","documentInfo.Category","documentInfo.Keywords","folders","services.name","services.type"];d.forEach(function(u){var t=i(u.split("."),r);if(t==null){return}if(t instanceof Array){t.forEach(function(v){o(s,u,v,q)})}else{o(s,u,t,q)}})}function p(q,u){var t=[],d={folders:function(r){return[q,r].join("/")},services:function(r){return[q,r.name.replace(/\w+\//ig,""),r.type].join("/")},layers:function(r){return[q,r.id].join("/")},tables:function(r){return[q,r.id].join("/")}},s;for(s in d){if(u[s]&&u[s].length){t=t.concat(u[s].map(d[s]))}}return t}function n(q,r){if(!q.length){return}var d=q.shift();m(d+"?f=json",function(t){k++;a(d,t,r);q=q.concat(p(d,t));if(q.length){n(q,r)}else{c.removeAttribute("disabled");c.innerHTML="Search";var s=l.createElement("li");s.innerHTML=["Places Searched:",k,"
    Results found",g].join(" ");f.insertBefore(s,f.firstChild)}})}function j(){var d,q;if(h.value){while(f.childNodes.length){f.removeChild(f.childNodes[0])}c.innerHTML="Scanning";c.setAttribute("disabled","disabled");if(/^\d*\.?\d+$/.test(h.value)){d=/\./.test(h.value)?parseFloat(h.value):parseInt(h.value,10);q=function(r){return r===d}}else{d=new RegExp(h.value,"i");q=function(r){return d.test(r)}}k=0;g=0;n([window.location.href.replace(window.location.search,"")],q)}else{alert("Please enter a value")}return false}b.setAttribute("style","position:fixed;top:5px;right:5px;width:300px;height:80%;overflow:auto;z-index:100;background:#fff;font-size:0.9em;");h.setAttribute("style","width:75%");b.appendChild(h);c.innerHTML="Search";c.onclick=j;b.appendChild(c);b.appendChild(f);l.body.appendChild(b)}()); -------------------------------------------------------------------------------- /SpatialRefCompare/README.md: -------------------------------------------------------------------------------- 1 | # Spatial Reference Comparison Tool (SpatialRefCompare.js) - ESRI REST Diagnostics 2 | 3 | A JavaScript bookmarklet for comparing the spatial references of map services on a page. 4 | 5 | ## Features 6 | 7 | This bookmarklet displays and color-codes the spatial references of each map service in a folder, and also lists whether the map service is tiled or dynamic. Layers with the same spatial reference (either by wkid or wkt) will show with the same color. If WKID is listed, a link to SpatialReference.org will be provided to view information on it. 8 | 9 | ## Instructions 10 | 11 | ### Installation 12 | 13 | Installation on the browser is as simple as adding a bookmark. From the [ESRI Rest Diagnostics](http://raykendo.github.io/ESRI_REST_Diagnostics/) page... 14 | 15 | - Chrome: drag the anchor link to your browser toolbar. 16 | - Firefox: right-click on the link and select "Bookmark this link". 17 | - IE: right-click on the link and select "Add to Favorites". 18 | - Safari: untested. 19 | - Opera: drag the anchor link to your browser toolbar. 20 | 21 | ### Basic Use 22 | 23 | In the browser, navigate to the map service REST endpoint. From there, select the Layer Data Extractor bookmarklet from the bookmark list. Scroll down the page to view data on each layer. 24 | 25 | ## Requirements 26 | 27 | - Desktop browser (IE8+, Chrome, Firefox) 28 | - Security settings that support bookmarklets. 29 | - Access to an ArcGIS Server REST endpoint in browser. 30 | 31 | ## Resources 32 | 33 | [ESRI JavaScript API](https://developers.arcgis.com/javascript/index.html) 34 | 35 | ## Contributing 36 | 37 | Anyone is welcome to contribute to this project. 38 | 39 | ## Licensing 40 | 41 | This is currently licensed under the MIT Licensing ([See License here](https://github.com/raykendo/ESRI_REST_Diagnostics/blob/master/LICENSE)). 42 | -------------------------------------------------------------------------------- /SpatialRefCompare/SpatialRefCompare.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | "use strict"; 3 | var d = document, 4 | tags = d.getElementsByTagName("a"), 5 | urls = [], 6 | colorhash = {}, 7 | i; 8 | function getFullLink(link) { 9 | var newLink = "", wl = window.location; 10 | if (link.indexOf(wl.protocol) === 0) { 11 | return link; 12 | } 13 | newLink += wl.protocol + "//"; 14 | if (link.indexOf(wl.hostname) === 0) { 15 | return newLink + link; 16 | } 17 | newLink += wl.hostname; 18 | if (link.indexOf(wl.pathname) === 0) { 19 | return newLink + link; 20 | } 21 | return newLink + wl.pathname + link; 22 | } 23 | function getColor(item) { 24 | if (colorhash[item]) { return colorhash[item]; } 25 | colorhash[item] = "#" + (0x1000000 + (Math.random()) * 0xffffff).toString(16).substr(1, 6); 26 | return colorhash[item]; 27 | } 28 | function getCompColor(item) { 29 | var col = colorhash[item], 30 | newcol = "", 31 | mid = [col.substr(1,1),col.substr(3,1),col.substr(5,1)].sort()[1], 32 | coltbl = "fedcba98".indexOf(mid) > -1 ? "0000000001234567" : "89abcdefffffffff", 33 | c; 34 | for (c = 0; c < col.length; c++) { 35 | newcol += c%2 === 1 ? coltbl[parseInt(col.substr(c,1), 16)] : col.substr(c, 1); 36 | } 37 | return newcol; 38 | } 39 | function srNode(sr) { 40 | var val=" No valid spatial reference available  ", 41 | el = "span", 42 | n; 43 | if (sr) { 44 | val = sr.latestWkid || sr.wkid || sr.latestWkt || sr.wkt || val; 45 | if (sr.latestWkid || sr.wkid) { 46 | el = "a"; 47 | } 48 | } 49 | n = d.createElement(el); 50 | if (el === "a") { 51 | n.setAttribute("href", "http://spatialreference.org/ref/?search=" + val); 52 | } 53 | n.setAttribute("style", ["color:", getColor(val), ";background:", getCompColor(val), ";"].join("")); 54 | n.innerHTML = val; 55 | return n; 56 | } 57 | // ajax function from https://gist.github.com/Xeoncross/7663273 58 | function ajax(u, callback, data, x) { 59 | try { 60 | x = new (window.XMLHttpRequest || ActiveXObject)("MSXML2.XMLHTTP.3.0"); 61 | x.open(data ? "POST" : "GET", u, 1); 62 | x.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 63 | x.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 64 | x.onreadystatechange = function () { 65 | x.readyState > 3 && callback && callback(x.responseText, x); 66 | }; 67 | x.send(data); 68 | } catch (e) { 69 | window.console && console.log(e); 70 | } 71 | } 72 | function queryMe(f) { 73 | if (!f.length) { return; } 74 | var data = f.shift(); 75 | ajax(data.url + "?f=json", 76 | function (response) { 77 | response = JSON.parse(response); 78 | var node = srNode(response.spatialReference), 79 | n2 = d.createElement("b"); 80 | n2.innerHTML = " " + response.singleFusedMapCache ? "tiled " : "dynamic "; 81 | //alert("" + data.i + ": " + tags.length); 82 | data.link.parentNode.appendChild(node); 83 | data.link.parentNode.appendChild(n2); 84 | if (f.length) { 85 | queryMe(f); 86 | } 87 | }); 88 | } 89 | 90 | for (i = 0; i < tags.length; i++) { 91 | // filter links for map service layers (index number at end); 92 | if (/(map|feature|image|mobile)server\/?$/i.test(tags[i].href)) { 93 | urls.push({link: tags[i], url: getFullLink(tags[i].href) }); 94 | } 95 | } 96 | // if there are services that fit the test, query them. 97 | if (urls && urls.length) { 98 | queryMe(urls); 99 | } else { 100 | alert("Pick a REST Service folder with services"); 101 | } 102 | }()); 103 | -------------------------------------------------------------------------------- /SpatialRefCompare/SpatialRefCompare.min.js: -------------------------------------------------------------------------------- 1 | (function(){"use strict";var e=document,m=e.getElementsByTagName("a"),f=[],l={},c;function b(i){var d="",n=window.location;if(i.indexOf(n.protocol)===0){return i}d+=n.protocol+"//";if(i.indexOf(n.hostname)===0){return d+i}d+=n.hostname;if(i.indexOf(n.pathname)===0){return d+i}return d+n.pathname+i}function j(d){if(l[d]){return l[d]}l[d]="#"+(16777216+(Math.random())*16777215).toString(16).substr(1,6);return l[d]}function a(p){var o=l[p],i="",n=[o.substr(1,1),o.substr(3,1),o.substr(5,1)].sort()[1],d="fedcba98".indexOf(n)>-1?"0000000001234567":"89abcdefffffffff",q;for(q=0;q3&&p&&p(d.responseText,d)};d.send(n)}catch(o){window.console&&console.log(o)}}function h(i){if(!i.length){return}var d=i.shift();g(d.url+"?f=json",function(n){n=JSON.parse(n);var p=k(n.spatialReference),o=e.createElement("b");o.innerHTML=" "+n.singleFusedMapCache?"tiled ":"dynamic ";d.link.parentNode.appendChild(p);d.link.parentNode.appendChild(o);if(i.length){h(i)}})}for(c=0;c 2 | 3 | 4 | ESRI REST Diagnoatics 5 | 6 | 7 |

    ESRI Rest Diagnostics

    8 |

    This page provides links to tools that can be used to inspect and pull out data out of ArcGIS REST Services.

    9 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /bookmarklets.json: -------------------------------------------------------------------------------- 1 | { 2 | "Map Folder Level:": { 3 | "contents": { 4 | "Spatial Reference Comparison": "SpatialRefCompare.min.js", 5 | "MapService Data Extractor v 0.3": "MapServiceData.min.js", 6 | "Map Viewer v. 0.5": "MapViewer.min.js" 7 | } 8 | }, 9 | "Map Service Level:": { 10 | "contents": { 11 | "Layer Property Extractor v. 0.1": "MapLayerData.min.js", 12 | "Layer Feature Counter v. 0.1": "MapLayerCount.min.js", 13 | "Tiled Service Tester v. 0.1": "TileTester.min.js", 14 | "Map Viewer v. 0.5": "MapViewer.min.js" 15 | } 16 | }, 17 | "Map Layer Level:": { 18 | "contents": { 19 | "Field Value Tester (null test only) v. 0.4": "FieldTester.min.js", 20 | "Populated Field Value Tester (null or empty string) v. 0.9": "FieldTester_NullOrEmpty.min.js", 21 | "Domain Data Counter v. 0.3": "DomainDataCounter.min.js" 22 | } 23 | }, 24 | "Query Page Level:": { 25 | "contents": { 26 | "Select By Attributes Query Helper v. 0.3": "QueryHelper.min.js", 27 | "Give me all Query Helper": "GiveMeAll_QueryHelper.min.js", 28 | "Count them Up Query Helper": "CountThemUp_QueryHelper.min.js", 29 | "Everything But Geometry Query Helper": "AllNoGeo_QueryHelper.min.js", 30 | "Select Distinct Query Helper": "SelectDistinct_QueryHelper.min.js" 31 | } 32 | }, 33 | "Miscellaneous:": { 34 | "contents": { 35 | "Rest Search v 0.5": "RestSearch.min.js", 36 | "Print Task Made Easy BETA": "PrintTaskMadeEasy.min.js", 37 | "Geometry Helper": "GeometryHelper.min.js" 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var del = require('del'); 3 | var bookmarklet = require('gulp-bookmarklet'); 4 | var netscape = require('netscape-bookmarks'); 5 | var through = require('through2'); 6 | var File = require('vinyl'); 7 | var bookmarklets_config = require('./bookmarklets.json'); 8 | 9 | gulp.task('esri_rest_diagnostics', ['bookmarklet'], function () { 10 | return gulp.src(["**/*.min.js", '!gulpfile.js', '!node_modules/**/*.*']) 11 | .pipe(esri_rest_diagnostics({"output_file": "bookmarklets.html"})) 12 | .pipe(gulp.dest("./")); 13 | }); 14 | 15 | gulp.task('bookmarklet', ['clean-min'], function () { 16 | return gulp.src(['**/*.js', '!./**/*.min.js', '!gulpfile.js', '!node_modules/**/*.*']) 17 | .pipe(bookmarklet({format: 'js'})) 18 | .pipe(gulp.dest('.')); 19 | }); 20 | 21 | gulp.task('bookmarklet-html', ['clean-min'], function () { 22 | return gulp.src(['**/*.js', '!./**/*.min.js', '!gulpfile.js', '!node_modules/**/*.*']) 23 | .pipe(bookmarklet({format: 'html'})) 24 | .pipe(gulp.dest('.')); 25 | }); 26 | 27 | gulp.task('bookmarklet-htmlsingle', ['clean-min'], function () { 28 | return gulp.src(['**/*.js', '!./**/*.min.js', '!gulpfile.js', '!node_modules/**/*.*']) 29 | .pipe(bookmarklet({format: 'htmlsingle', file: 'bookmarklets_raw.html'})) 30 | .pipe(gulp.dest('.')); 31 | }); 32 | 33 | gulp.task('clean-min', function () { 34 | return del(['**/*.min.js', 'bookmarklets.html']); 35 | }); 36 | 37 | gulp.task('default', ['esri_rest_diagnostics']); 38 | 39 | var esri_rest_diagnostics = function (args) { 40 | var opt = args || {}; 41 | var output_file_name = opt.output_file || "bookmarklets.html"; 42 | 43 | return through.obj(function (file, encoding, callback) { 44 | function generate_bookmarklets_html(file) { 45 | var file_delimiter = file.path.toString().indexOf("\\") > -1 ? "\\" : "/"; 46 | var file_name = file.path.split(file_delimiter).pop(); 47 | Object.keys(bookmarklets_config).forEach(function (section) { 48 | Object.keys(bookmarklets_config[section].contents).forEach(function (bookmark) { 49 | var bookmark_file_name = bookmarklets_config[section].contents[bookmark]; 50 | if (bookmark_file_name.toLowerCase() === file_name.toLowerCase()) { 51 | bookmarklets_config[section].contents[bookmark] = file.contents.toString(); 52 | } 53 | }); 54 | }); 55 | } 56 | callback(null, generate_bookmarklets_html(file)); 57 | }, function (callback) { 58 | var html = netscape(bookmarklets_config); 59 | 60 | html = html.replace(/Bookmarks\ Menu/gi, "ESRI Rest Diagnostics"); 61 | html = html.replace(/Bookmarks/gi, "ESRI Rest Diagnostics"); 62 | html = html.replace(/<\/H1>/gi, "

    This page provides links to tools that can be used to inspect and pull out data out of ArcGIS REST Services.

    "); 63 | html = html.replace(/
    /gi, "
      "); 64 | html = html.replace(/<\/DL>/gi, "
    "); 65 | html = html.replace(/
    /gi, "
  • "); 66 | html = html.replace(/<\/DT>/gi, "
  • "); 67 | html = html.replace(/

    /gi, ""); 68 | html = html.replace(/<\/H3>/gi, ""); 69 | html = html.replace(/

      /gi, "

        "); 70 | html = html.replace(/<\/UL>

        /gi, "

      "); 71 | html += ""; 72 | 73 | var bookmarklet_file = new File({ 74 | path: output_file_name, 75 | contents: new Buffer(html) 76 | }); 77 | 78 | this.push(bookmarklet_file); 79 | callback(null); 80 | }); 81 | }; 82 | -------------------------------------------------------------------------------- /images/Install_Chrome.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raykendo/ESRI_REST_Diagnostics/a28c6f7ab96071258009171e6abe1ee40a4b1fe6/images/Install_Chrome.gif -------------------------------------------------------------------------------- /images/Install_Firefox.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raykendo/ESRI_REST_Diagnostics/a28c6f7ab96071258009171e6abe1ee40a4b1fe6/images/Install_Firefox.gif -------------------------------------------------------------------------------- /images/Install_IE.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raykendo/ESRI_REST_Diagnostics/a28c6f7ab96071258009171e6abe1ee40a4b1fe6/images/Install_IE.gif -------------------------------------------------------------------------------- /images/Install_Opera.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raykendo/ESRI_REST_Diagnostics/a28c6f7ab96071258009171e6abe1ee40a4b1fe6/images/Install_Opera.gif -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esri_rest_diagnostics", 3 | "version": "1.0.0", 4 | "description": "ESRI Rest Diagnostics - A bookmarklet set to collect data from and to test ArcGIS Server REST Services.", 5 | "main": "gulpfile.js", 6 | "dependencies": { 7 | "gulp": "^3.9.1", 8 | "gulp-bookmarklet": "^1.0.0", 9 | "netscape-bookmarks": "^0.0.0", 10 | "del": "^2.2.0", 11 | "through2": "^2.0.1", 12 | "vinyl": "^1.1.1" 13 | }, 14 | "devDependencies": {}, 15 | "scripts": { 16 | "test": "echo \"Error: no test specified\" && exit 1" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/raykendo/ESRI_REST_Diagnostics.git" 21 | }, 22 | "author": "Ken Doman", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/raykendo/ESRI_REST_Diagnostics/issues" 26 | }, 27 | "homepage": "http://raykendo.github.io/ESRI_REST_Diagnostics" 28 | } 29 | --------------------------------------------------------------------------------