{"id":5266,"date":"2016-05-13T07:06:33","date_gmt":"2016-05-13T10:06:33","guid":{"rendered":"http:\/\/www.fernandoquadro.com.br\/html\/?p=5266"},"modified":"2018-09-04T12:27:56","modified_gmt":"2018-09-04T15:27:56","slug":"criando-um-mapa-de-calor-no-geoserver-com-wps-parte-3","status":"publish","type":"post","link":"https:\/\/www.fernandoquadro.com.br\/html\/2016\/05\/13\/criando-um-mapa-de-calor-no-geoserver-com-wps-parte-3\/","title":{"rendered":"Criando um mapa de calor no GeoServer com WPS (Parte 3)"},"content":{"rendered":"<p>Neste post iremos finalizar nosso artigo construindo uma aplica\u00e7\u00e3o para apresentar o nosso mapa de calor. Para isso voc\u00ea vai precisar para construir o aplicativo em algum lugar que seja acess\u00edvel por um navegador web.<\/p>\n<p>O mapa simples que podemos desenvolver usa apenas uma p\u00e1gina com OpenLayers que mostra um mapa base e nossa camada WMS (geonames). Para isso voc\u00ea vai precisar de dois arquivos, <a href=\"http:\/\/workshops.boundlessgeo.com\/tutorial-wordmap\/_static\/basic-openlayers.html\" target=\"_blank\">basic-openlayers.html<\/a> e <a href=\"http:\/\/workshops.boundlessgeo.com\/tutorial-wordmap\/_static\/basic-openlayers.js\" target=\"_blank\">basic-openlayers.js<\/a>. No documento HTML coloque o seguinte:<\/p>\n<pre>&lt;html&gt;\r\n&nbsp;&nbsp;&lt;head&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;title&gt;Basic Word Map&lt;\/title&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;script src=\"http:\/\/www.openlayers.org\/api\/2.12\/OpenLayers.js\"&gt;&lt;\/script&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;script src=\"basic-openlayers.js\"&gt;&lt;\/script&gt;\r\n&nbsp;&nbsp;&lt;\/head&gt;\r\n&nbsp;&nbsp;&lt;body onLoad=\"initMap()\"&gt;\r\n&nbsp;&nbsp;&lt;div id=\"map\"&gt;&lt;\/div&gt;\r\n&nbsp;&nbsp;&lt;\/body&gt;\r\n&lt;\/html&gt;\r\n&lt;html&gt;\r\n&nbsp;&nbsp;&lt;head&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;title&gt;Basic Word Map&lt;\/title&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;script src=\"http:\/\/www.openlayers.org\/api\/2.12\/OpenLayers.js\"&gt;&lt;\/script&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;script src=\"basic-openlayers.js\"&gt;&lt;\/script&gt;\r\n&nbsp;&nbsp;&lt;\/head&gt;\r\n&nbsp;&nbsp;&lt;body onLoad=\"initMap()\"&gt;\r\n&nbsp;&nbsp;&lt;div id=\"map\"&gt;&lt;\/div&gt;\r\n&nbsp;&nbsp;&lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<p>O documento HTML apenas faz refer\u00eancia ao nosso arquivo javascript (OpenLayers) do aplicativo, e estabelece uma chamada &#8220;map&#8221; para realizar o v\u00ednculo com o OpenLayers. No documento JavaScript, coloque o seguinte c\u00f3digo:<\/p>\n<pre>function initMap() {\r\n&nbsp;&nbsp;\/\/ Create the map\r\n&nbsp;&nbsp;var map = new OpenLayers.Map(\"map\");\r\n&nbsp;&nbsp;\/\/ Create a WMS layer, with a base layer (states) and names layer (geonames)\r\n&nbsp;&nbsp;var&nbsp;wms = new OpenLayers.Layer.WMS(\"GeoServer WMS\",\r\n&nbsp;&nbsp;&nbsp;&nbsp;\"http:\/\/localhost:8080\/geoserver\/wms\",\r\n&nbsp;&nbsp;&nbsp;&nbsp;{\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;layers: \"usa:states,opengeo:geonames\"\r\n&nbsp;&nbsp;&nbsp;&nbsp;});\r\n&nbsp;&nbsp;\/\/ Set the word parameter for the geonames layer\r\n&nbsp;&nbsp;var myWord = \"Navajo\";\r\n&nbsp;&nbsp;wms.mergeNewParams({viewparams: \"word:\" + myWord});\r\n&nbsp;&nbsp;\/\/ Add the layer to the map and center the map on the USA\r\n&nbsp;&nbsp;map.addLayer(wms);\r\n&nbsp;&nbsp;map.setCenter(new OpenLayers.LonLat(-100, 38), 5);\r\n}<\/pre>\n<p>O arquivo Javascript usa como base a camada &#8220;states&#8221; do GeoServer para servir como contexto para a camada &#8220;geonames&#8221;. <\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/05\/ol-navajo.png\" alt=\"ol-navajo\" width=\"771\" height=\"576\" class=\"aligncenter size-full wp-image-5309\" srcset=\"https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/05\/ol-navajo.png 771w, https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/05\/ol-navajo-300x224.png 300w, https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/05\/ol-navajo-768x574.png 768w, https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/05\/ol-navajo-600x448.png 600w\" sizes=\"auto, (max-width: 771px) 100vw, 771px\" \/><\/p>\n<p>Agora altere o valor da v\u00e1riavel &#8220;myWord&#8221; e recarregue a p\u00e1gina para ver os diferentes resultados no mapa.<\/p>\n<p>Isto \u00e9 muito interessante, mas seria ainda melhor se pud\u00e9ssemos digitar uma palavra e imediatamente ver a mudan\u00e7a do mapa, sem precisar recarreg\u00e1-la. Queremos tamb\u00e9m visualizar os resultados atrav\u00e9s de um mapa de calor, n\u00e3o apenas um mapa de pontos!<\/p>\n<p>Para construir nossa aplica\u00e7\u00e3o final, usaremos o <a href=\"http:\/\/www.sencha.com\/products\/extjs\" target=\"_blank\">ExtJS<\/a>, com a biblioteca <a href=\"http:\/\/www.geoext.org\/\" target=\"_blank\">GeoExt<\/a>. Assim como acontece com os exemplos do <a href=\"http:\/\/openlayers.org\/\" target=\"_blank\">OpenLayers<\/a>, a p\u00e1gina HTML do ExtJS \u00e9 muito simples, pois \u00e9 apenas um lugar para declarar as refer\u00eancias das bibliotecas que ser\u00e3o utilizadas. <\/p>\n<pre>&lt;html&gt;\r\n&nbsp;&nbsp;&lt;head&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;title&gt;OpenGeo Word Map&lt;\/title&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- ExtJS Scripts and Styles --&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;script type=\"text\/javascript\" src=\"http:\/\/cdn.sencha.com\/ext\/gpl\/3.4.1.1\/adapter\/ext\/ext-base.js\"&gt;&lt;\/script&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;script type=\"text\/javascript\" src=\"http:\/\/cdn.sencha.com\/ext\/gpl\/3.4.1.1\/ext-all.js\"&gt;&lt;\/script&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;link rel=\"stylesheet\" type=\"text\/css\" href=\"http:\/\/cdn.sencha.com\/ext\/gpl\/3.4.1.1\/resources\/css\/ext-all.css\" \/&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;link rel=\"stylesheet\" type=\"text\/css\" href=\"http:\/\/cdn.sencha.com\/ext\/gpl\/3.4.1.1\/examples\/shared\/examples.css\" \/&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- OpenLayers Script --&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;script src=\"http:\/\/www.openlayers.org\/api\/2.12\/OpenLayers.js\"&gt;&lt;\/script&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- GeoExt Script --&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;script type=\"text\/javascript\" src=\"http:\/\/api.geoext.org\/1.1\/script\/GeoExt.js\"&gt;&lt;\/script&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- Our Application --&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;script type=\"text\/javascript\" src=\"wordmap-simple.js\"&gt;&lt;\/script&gt;\r\n&nbsp;&nbsp;&lt;\/head&gt;\r\n&nbsp;&nbsp;&lt;body&gt;\r\n&nbsp;&nbsp;&lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<p>Voc\u00ea pode perceber que no arquivo HTML acima, s\u00e3o declaradas as bibliotecas ExtJS, GeoExt, OpenLayers e tamb\u00e9m o documento &#8220;<a href=\"http:\/\/workshops.boundlessgeo.com\/tutorial-wordmap\/_static\/wordmap-simple.js\" target=\"_blank\">wordmap-simple.js<\/a>&#8221; que nada mais \u00e9 que a nossa aplica\u00e7\u00e3o. Veja:<\/p>\n<pre>\/\/ Use this word on startup\r\nvar startWord = \"Ocean\";\r\n\/\/ Base map\r\nvar osmLayer = new OpenLayers.Layer.OSM();\r\n\/\/ Point map\r\nvar wmsLayer = new OpenLayers.Layer.WMS(\"WMS\", \"http:\/\/localhost:8080\/geoserver\/wms\", {\r\n&nbsp;&nbsp;format: \"image\/png\",\r\n&nbsp;&nbsp;transparent: true,\r\n&nbsp;&nbsp;layers: \"opengeo:geonames\",\r\n&nbsp;&nbsp;styles: \"point\"\r\n}, {\r\n&nbsp;&nbsp;opacity: 0.6,\r\n&nbsp;&nbsp;singleTile: true,\r\n});\r\n\/\/ Start with map of startWord\r\nwmsLayer.mergeNewParams({viewparams: \"word:\"+startWord});<\/pre>\n<p>Tal como acontece com o nosso exemplo simples, come\u00e7amos definindo nossas camadas: o OpenStreetMap como mapa base; e a nossa camada WMS. Temos algumas op\u00e7\u00f5es extras na defini\u00e7\u00e3o da camada WMS no OpenLayers, pois a definimos para ter um fundo transparente, e uma opacidade parcial, isso para sobrepor o mapa base.<\/p>\n<p>N\u00f3s tamb\u00e9m definimos uma vari\u00e1vel com nome de &#8220;startWord&#8221;, que ir\u00e1 iniciar o mapeamento da aplica\u00e7\u00e3o ao set\u00e1-la no par\u00e2metro da URL.<\/p>\n<p>Agora as coisas come\u00e7am a ficam um pouco mais complicadas:<\/p>\n<pre>\/\/ Map with projection into (required when mixing base map with WMS)\r\nolMap = new OpenLayers.Map({\r\n&nbsp;&nbsp;projection: \"EPSG:900913\",\r\n&nbsp;&nbsp;center: [-10764594.0, 4523072.0],\r\n&nbsp;&nbsp;units: \"m\",\r\n&nbsp;&nbsp;layers: [wmsLayer, osmLayer],\r\n&nbsp;&nbsp;zoom: 4\r\n});<\/pre>\n<p>Como estamos misturando um mapa WMS e um mapa do OSM, n\u00f3s precisamos:<\/p>\n<p>1. Garantir que a camada WMS declare a proje\u00e7\u00e3o que est\u00e1 usando, que deve ser a Mercator para coincidir com o mapa base (OSM); e,<br \/>\n2. Garantir que o ponto central est\u00e1 convertido em Mercator antes de ser iniciado o mapa.<\/p>\n<p>Agora que o mapa est\u00e1 configurado, s\u00f3 precisamos reunir os componentes ExtJS em uma aplica\u00e7\u00e3o:<\/p>\n<pre>\/\/ Text field component. On 'enter' update the WMS URL\r\nvar textField = new Ext.form.TextField({\r\n&nbsp;&nbsp;value: startWord,\r\n&nbsp;&nbsp;listeners: {\r\n&nbsp;&nbsp;&nbsp;&nbsp;specialkey: function(fld, e) {\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/ Only update the map when the user hits 'enter'\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (e.getKey() == e.ENTER) {\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wmsLayer.mergeNewParams({viewparams: \"word:\"+fld.getValue()});\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\r\n&nbsp;&nbsp;&nbsp;&nbsp;}\r\n&nbsp;&nbsp;}\r\n});<\/pre>\n<p>Para introduzir novas palavras precisamos de um campo de texto na tela. Quando o usu\u00e1rio clicar, ele deve pegar o evento e atualizar a camada (WMS).<\/p>\n<pre>\/\/ Map panel, with text field embedded in top toolbar\r\nvar mapPanel = new GeoExt.MapPanel({\r\n&nbsp;&nbsp;title: \"OpenGeo Geonames Heat Map\",\r\n&nbsp;&nbsp;tbar: [\"Enter a word to map:\", textField],\r\n&nbsp;&nbsp;map: olMap\r\n});<\/pre>\n<p>Agora iremos adicionar um painel com o campo de texto embutido na barra de ferramentas no topo da tela:<\/p>\n<pre>\/\/ Viewport wraps map panel in full-screen handler\r\nvar viewPort = new Ext.Viewport({\r\n&nbsp;&nbsp;layout: \"fit\",\r\n&nbsp;&nbsp;items: [mapPanel]\r\n});\r\n\/\/ Start the app!\r\nExt.onReady(function () {\r\n&nbsp;&nbsp;viewPort.show();\r\n});<\/pre>\n<p>Para finalizamos nossa aplica\u00e7\u00e3o vamos ver como ficou o nosso c\u00f3digo em um \u00fanico bloco:<\/p>\n<pre>\/\/ Use this word on startup\r\nvar startWord = \"ocean\";\r\n\/\/ Base map\r\nvar osmLayer = new OpenLayers.Layer.OSM();\r\n\/\/ Heat map + point map\r\nvar wmsLayer = new OpenLayers.Layer.WMS(\"WMS\",\r\n&nbsp;&nbsp;\/\/ Uncomment below to use your local server\r\n&nbsp;&nbsp;\/\/ \"http:\/\/localhost:8080\/geoserver\/wms\",\r\n&nbsp;&nbsp;\"http:\/\/apps.opengeo.org\/geoserver\/wms\",\r\n&nbsp;&nbsp;{\r\n&nbsp;&nbsp;&nbsp;&nbsp;format: \"image\/png8\",\r\n&nbsp;&nbsp;&nbsp;&nbsp;transparent: true,\r\n&nbsp;&nbsp;&nbsp;&nbsp;layers: \"opengeo:geonames,opengeo:geonames\",\r\n&nbsp;&nbsp;&nbsp;&nbsp;styles: \"point,heatmap\"\r\n&nbsp;&nbsp;}, {\r\n&nbsp;&nbsp;&nbsp;&nbsp;opacity: 0.6,\r\n&nbsp;&nbsp;&nbsp;&nbsp;singleTile: true,\r\n&nbsp;&nbsp;});\r\n\/\/ Start with map of startWord\r\nwmsLayer.mergeNewParams({viewparams: \"word:\"+startWord});\r\n\/\/ Map with projection into (required when mixing base map with WMS)\r\nolMap = new OpenLayers.Map({\r\n&nbsp;&nbsp;projection: \"EPSG:900913\",\r\n&nbsp;&nbsp;units: \"m\",\r\n&nbsp;&nbsp;layers: [wmsLayer, osmLayer],\r\n&nbsp;&nbsp;center: [-10764594.0, 4523072.0],\r\n&nbsp;&nbsp;zoom: 4\r\n});\r\n\/\/ Take in user input, fire an event when complete\r\nvar textField = new Ext.form.TextField({\r\n&nbsp;&nbsp;value: startWord,\r\n&nbsp;&nbsp;listeners: {\r\n&nbsp;&nbsp;&nbsp;&nbsp;specialkey: function(field, e) {\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/ Only update the word map when user hits 'enter'\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (e.getKey() == e.ENTER) {\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wmsLayer.mergeNewParams({viewparams: \"word:\"+field.getValue()});\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\r\n&nbsp;&nbsp;&nbsp;&nbsp;}\r\n&nbsp;&nbsp;}\r\n});\r\n\/\/ Map panel, with text field embedded in top toolbar\r\nvar mapPanel = new GeoExt.MapPanel({\r\n&nbsp;&nbsp;title: \"OpenGeo Geonames Heat Map\",\r\n&nbsp;&nbsp;tbar: [\"Enter a word to map:\", textField],\r\n&nbsp;&nbsp;map: olMap\r\n});\r\n\/\/ Viewport wraps map panel in full-screen handler\r\nvar viewPort = new Ext.Viewport({\r\n&nbsp;&nbsp;layout: \"fit\",\r\n&nbsp;&nbsp;items: [mapPanel]\r\n});\r\n\/\/ Start the app!\r\nExt.onReady(function () {\r\n&nbsp;&nbsp;viewPort.show();\r\n});<\/pre>\n<p>Veja agora como ficou o nosso mapa:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/05\/ext-ocean.png\" alt=\"ext-ocean\" width=\"701\" height=\"533\" class=\"aligncenter size-full wp-image-5320\" srcset=\"https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/05\/ext-ocean.png 701w, https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/05\/ext-ocean-300x228.png 300w, https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/05\/ext-ocean-600x456.png 600w\" sizes=\"auto, (max-width: 701px) 100vw, 701px\" \/><\/p>\n<p>Assim, ficou uma aplica\u00e7\u00e3o muito bonita, mas foi prometido um mapa de calor, e at\u00e9 agora, este \u00e9 apenas um mapa de pontos! N\u00f3s precisamos adicionar um estilo de mapa de calor:<\/p>\n<p>1. Clique em &#8220;Style&#8221; na barra de navega\u00e7\u00e3o do GeoServer<br \/>\n2. Selecione &#8220;Add new style&#8221;<br \/>\n3. Adicione o nome do estilo como &#8220;heatmap&#8221;<br \/>\n4. Cole o c\u00f3digo abaixo na \u00e1rea de c\u00f3digo<\/p>\n<pre>&lt;?xml&nbsp;version=\"1.0\"&nbsp;encoding=\"ISO-8859-1\"?&gt;\r\n&lt;StyledLayerDescriptor&nbsp;version=\"1.0.0\"\r\n&nbsp;&nbsp;&nbsp;xsi:schemaLocation=\"http:\/\/www.opengis.net\/sld&nbsp;StyledLayerDescriptor.xsd\"\r\n&nbsp;&nbsp;&nbsp;xmlns=\"http:\/\/www.opengis.net\/sld\"\r\n&nbsp;&nbsp;&nbsp;xmlns:ogc=\"http:\/\/www.opengis.net\/ogc\"\r\n&nbsp;&nbsp;&nbsp;xmlns:xlink=\"http:\/\/www.w3.org\/1999\/xlink\"\r\n&nbsp;&nbsp;&nbsp;xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"&gt;\r\n&nbsp;&nbsp;&lt;NamedLayer&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;Name&gt;Heatmap&lt;\/Name&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;UserStyle&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Title&gt;Heatmap&lt;\/Title&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Abstract&gt;A&nbsp;heatmap&nbsp;surface&lt;\/Abstract&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;FeatureTypeStyle&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Transformation&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Function&nbsp;name=\"gs:Heatmap\"&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Function&nbsp;name=\"parameter\"&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Literal&gt;data&lt;\/ogc:Literal&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/ogc:Function&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Function&nbsp;name=\"parameter\"&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Literal&gt;radiusPixels&lt;\/ogc:Literal&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Function&nbsp;name=\"env\"&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Literal&gt;radius&lt;\/ogc:Literal&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Literal&gt;100&lt;\/ogc:Literal&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/ogc:Function&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/ogc:Function&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Function&nbsp;name=\"parameter\"&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Literal&gt;pixelsPerCell&lt;\/ogc:Literal&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Literal&gt;10&lt;\/ogc:Literal&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/ogc:Function&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Function&nbsp;name=\"parameter\"&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Literal&gt;outputBBOX&lt;\/ogc:Literal&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Function&nbsp;name=\"env\"&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Literal&gt;wms_bbox&lt;\/ogc:Literal&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/ogc:Function&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/ogc:Function&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Function&nbsp;name=\"parameter\"&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Literal&gt;outputWidth&lt;\/ogc:Literal&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Function&nbsp;name=\"env\"&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Literal&gt;wms_width&lt;\/ogc:Literal&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/ogc:Function&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/ogc:Function&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Function&nbsp;name=\"parameter\"&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Literal&gt;outputHeight&lt;\/ogc:Literal&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Function&nbsp;name=\"env\"&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:Literal&gt;wms_height&lt;\/ogc:Literal&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/ogc:Function&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/ogc:Function&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/ogc:Function&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/Transformation&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Rule&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;RasterSymbolizer&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;specify&nbsp;geometry&nbsp;attribute&nbsp;to&nbsp;pass&nbsp;validation&nbsp;--&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Geometry&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ogc:PropertyName&gt;geom&lt;\/ogc:PropertyName&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/Geometry&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Opacity&gt;0.6&lt;\/Opacity&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ColorMap&nbsp;type=\"ramp\"&nbsp;&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ColorMapEntry&nbsp;color=\"#FFFFFF\"&nbsp;quantity=\"0\"&nbsp;&nbsp;&nbsp;&nbsp;label=\"nodata\"&nbsp;opacity=\"0\"&nbsp;\/&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ColorMapEntry&nbsp;color=\"#FFFFFF\"&nbsp;quantity=\"0.02\"&nbsp;label=\"nodata\"&nbsp;opacity=\"0\"&nbsp;\/&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ColorMapEntry&nbsp;color=\"#4444FF\"&nbsp;quantity=\".1\"&nbsp;&nbsp;&nbsp;label=\"nodata\"&nbsp;\/&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ColorMapEntry&nbsp;color=\"#FF0000\"&nbsp;quantity=\".5\"&nbsp;&nbsp;&nbsp;label=\"values\"&nbsp;\/&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ColorMapEntry&nbsp;color=\"#FFFF00\"&nbsp;quantity=\"1.0\"&nbsp;&nbsp;label=\"values\"&nbsp;\/&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/ColorMap&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/RasterSymbolizer&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/Rule&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/FeatureTypeStyle&gt;\r\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/UserStyle&gt;\r\n&nbsp;&nbsp;&lt;\/NamedLayer&gt;\r\n&lt;\/StyledLayerDescriptor&gt;<\/pre>\n<p>Em seguida, clique no bot\u00e3o &#8220;Salvar&#8221;, e est\u00e1 pronto o nosso estilo heatmap! (Os par\u00e2metros do estilo s\u00e3o <a href=\"http:\/\/docs.geoserver.org\/stable\/en\/user\/styling\/sld-extensions\/rendering-transform.html#heatmap-generation\" target=\"_blank\">explicados aqui<\/a>). <\/p>\n<p>Ao invocar a fun\u00e7\u00e3o gs:Heatmap no estilo, o GeoServer est\u00e1 utilizando o m\u00e9todo heatmap dispon\u00edvel no servi\u00e7o WPS (Web Process Service), que realiza o processamento e disponibiliza a camada atrav\u00e9s do WMS.<\/p>\n<p>Para ativar o mapa de calor em nossa aplica\u00e7\u00e3o, n\u00f3s s\u00f3 precisamos especificar esse estilo em nossa camada WMS. Ent\u00e3o vamos fazer esta mudan\u00e7a na aplica\u00e7\u00e3o:<\/p>\n<pre>\/\/&nbsp;Heat&nbsp;map&nbsp;+&nbsp;point&nbsp;map\r\nvar&nbsp;wmsLayer&nbsp;=&nbsp;new&nbsp;OpenLayers.Layer.WMS(\"WMS\",&nbsp;\"http:\/\/localhost:8080\/geoserver\/wms\",&nbsp;{\r\n&nbsp;&nbsp;format:&nbsp;\"image\/png\",\r\n&nbsp;&nbsp;transparent:&nbsp;true,\r\n&nbsp;&nbsp;layers:&nbsp;\"opengeo:geonames,opengeo:geonames\",\r\n&nbsp;&nbsp;styles:&nbsp;\"point,heatmap\"\r\n},&nbsp;{\r\n&nbsp;&nbsp;opacity:&nbsp;0.6,\r\n&nbsp;&nbsp;singleTile:&nbsp;true,\r\n});<\/pre>\n<p>Note que, em vez de substituir o nosso estilo de ponto, estamos adicionando um estilo heatmap a mesma camada (opengeo:GeoNames) uma segunda vez. Isso nos permite ver os pontos originais, bem como o mapa de calor.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/05\/ext-ocean-heat.png\" alt=\"ext-ocean-heat\" width=\"701\" height=\"534\" class=\"aligncenter size-full wp-image-5323\" srcset=\"https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/05\/ext-ocean-heat.png 701w, https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/05\/ext-ocean-heat-300x229.png 300w, https:\/\/www.fernandoquadro.com.br\/html\/wp-content\/uploads\/2016\/05\/ext-ocean-heat-600x457.png 600w\" sizes=\"auto, (max-width: 701px) 100vw, 701px\" \/><\/p>\n<p>Este tutorial \u00e9 uma tradu\u00e7\u00e3o e adapta\u00e7\u00e3o livre do artigo &#8220;<a href=\"http:\/\/workshops.boundlessgeo.com\/tutorial-wordmap\/\" target=\"_blank\">Building a GeoNames Heat Map<\/a>&#8221; publicado no site da Boundless.<\/p>\n<p>Fonte: <a href=\"http:\/\/workshops.boundlessgeo.com\/tutorial-wordmap\/\" target=\"_blank\">Boundless<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Neste post iremos finalizar nosso artigo construindo uma aplica\u00e7\u00e3o para apresentar o nosso mapa de calor. Para isso voc\u00ea vai precisar para construir o aplicativo em algum lugar que seja acess\u00edvel por um navegador web. O mapa simples que podemos&#8230; <a class=\"more-link\" href=\"https:\/\/www.fernandoquadro.com.br\/html\/2016\/05\/13\/criando-um-mapa-de-calor-no-geoserver-com-wps-parte-3\/\">Continue Reading &rarr;<\/a><\/p>\n","protected":false},"author":275,"featured_media":5303,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,132,62],"tags":[223,250,264],"class_list":["post-5266","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-gis","category-openlayers","category-wps","tag-gis","tag-openlayers","tag-wps"],"_links":{"self":[{"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/posts\/5266","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/users\/275"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/comments?post=5266"}],"version-history":[{"count":21,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/posts\/5266\/revisions"}],"predecessor-version":[{"id":7289,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/posts\/5266\/revisions\/7289"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/media\/5303"}],"wp:attachment":[{"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/media?parent=5266"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/categories?post=5266"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fernandoquadro.com.br\/html\/wp-json\/wp\/v2\/tags?post=5266"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}