{"id":7601,"date":"2022-12-07T22:10:39","date_gmt":"2022-12-08T03:10:39","guid":{"rendered":"https:\/\/weather.umd.edu\/wordpress\/?page_id=7601"},"modified":"2024-11-23T00:19:05","modified_gmt":"2024-11-23T05:19:05","slug":"micronet-map","status":"publish","type":"page","link":"https:\/\/weather.umd.edu\/wordpress\/micronet\/micronet-map\/","title":{"rendered":"Station Map"},"content":{"rendered":"\n\n        <div id=\"map\"><\/div>\r\n\r\n        <link rel=\"stylesheet\" href=\"https:\/\/unpkg.com\/leaflet@1.9.3\/dist\/leaflet.css\"\r\n            integrity=\"sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI=\"\r\n            crossorigin=\"\"\/>\r\n\r\n        <style>\r\n            #map {\r\n                height: 600px;\r\n            }\r\n            .circle {\r\n                display: table-cell;\r\n                text-align: center;\r\n                vertical-align: middle;\r\n                border-radius: 50%;\r\n                border-style: solid;\r\n                font-size: 16px;\r\n                font-weight: bold;\r\n            }\r\n            .circle.circle1 {\r\n                background: rgba(0, 57, 128, 0.2);\r\n                border-color: #3388FF;\r\n                color: white;\r\n            }\r\n            .circle.circle2 {\r\n                background: rgba(0, 57, 128, 0.2);\r\n                border-color: green;\r\n                color: yellow;\r\n            }\r\n        <\/style>\r\n\r\n        <script src=\"https:\/\/unpkg.com\/leaflet@1.9.3\/dist\/leaflet.js\"\r\n            integrity=\"sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM=\"\r\n            crossorigin=\"\"><\/script>\r\n\r\n        <script src=\"https:\/\/weather.umd.edu\/wordpress\/wp-content\/plugins\/meso-fsct\/widget\/js-colormaps\/js-colormaps.js\"><\/script>\r\n\r\n        <script>\r\n\r\n            \/\/ Rotated marker hack\r\n            var proto_initIcon = L.Marker.prototype._initIcon;\r\n            var proto_setPos = L.Marker.prototype._setPos;\r\n            var oldIE = (L.DomUtil.TRANSFORM === 'msTransform');\r\n\r\n            L.Marker.addInitHook(function () {\r\n                var iconOptions = this.options.icon && this.options.icon.options;\r\n                var iconAnchor = iconOptions && this.options.icon.options.iconAnchor;\r\n                if (iconAnchor) {\r\n                    iconAnchor = (iconAnchor[0] + 'px ' + iconAnchor[1] + 'px');\r\n                }\r\n                this.options.rotationOrigin = this.options.rotationOrigin || iconAnchor || 'center bottom';\r\n                this.options.rotationAngle = this.options.rotationAngle || 0;\r\n                this.on('drag', function(e) { e.target._applyRotation(); });\r\n            });\r\n\r\n            L.Marker.include({\r\n                _initIcon: function() {\r\n                    proto_initIcon.call(this);\r\n                },\r\n                _setPos: function (pos) {\r\n                    proto_setPos.call(this, pos);\r\n                    this._applyRotation();\r\n                },\r\n                _applyRotation: function () {\r\n                    if(this.options.rotationAngle) {\r\n                        this._icon.style[L.DomUtil.TRANSFORM+'Origin'] = this.options.rotationOrigin;\r\n                        if(oldIE) {\r\n                            this._icon.style[L.DomUtil.TRANSFORM] = 'rotate(' + this.options.rotationAngle + 'deg)';\r\n                        } else {\r\n                            this._icon.style[L.DomUtil.TRANSFORM] += ' rotateZ(' + this.options.rotationAngle + 'deg)';\r\n                        }\r\n                    }\r\n                },\r\n                setRotationAngle: function(angle) {\r\n                    this.options.rotationAngle = angle;\r\n                    this.update();\r\n                    return this;\r\n                },\r\n                setRotationOrigin: function(origin) {\r\n                    this.options.rotationOrigin = origin;\r\n                    this.update();\r\n                    return this;\r\n                }\r\n            });\r\n\r\n            barbSymbols = [\r\n                '',\r\n                'https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6a\/Symbol_wind_speed_01.svg',\r\n                'https:\/\/upload.wikimedia.org\/wikipedia\/commons\/4\/43\/Symbol_wind_speed_02.svg',\r\n                'https:\/\/upload.wikimedia.org\/wikipedia\/commons\/5\/5a\/Symbol_wind_speed_03.svg',\r\n                'https:\/\/upload.wikimedia.org\/wikipedia\/commons\/c\/c8\/Symbol_wind_speed_04.svg',\r\n                'https:\/\/upload.wikimedia.org\/wikipedia\/commons\/e\/ec\/Symbol_wind_speed_05.svg',\r\n                'https:\/\/upload.wikimedia.org\/wikipedia\/commons\/9\/9c\/Symbol_wind_speed_06.svg',\r\n                'https:\/\/upload.wikimedia.org\/wikipedia\/commons\/7\/70\/Symbol_wind_speed_07.svg',\r\n                'https:\/\/upload.wikimedia.org\/wikipedia\/commons\/c\/c1\/Symbol_wind_speed_08.svg',\r\n                'https:\/\/upload.wikimedia.org\/wikipedia\/commons\/2\/28\/Symbol_wind_speed_09.svg',\r\n                'https:\/\/upload.wikimedia.org\/wikipedia\/commons\/d\/d2\/Symbol_wind_speed_10.svg',\r\n                'https:\/\/upload.wikimedia.org\/wikipedia\/commons\/2\/21\/Symbol_wind_speed_11.svg',\r\n                'https:\/\/upload.wikimedia.org\/wikipedia\/commons\/6\/6d\/Symbol_wind_speed_12.svg',\r\n                'https:\/\/upload.wikimedia.org\/wikipedia\/commons\/7\/79\/Symbol_wind_speed_13.svg',\r\n                'https:\/\/upload.wikimedia.org\/wikipedia\/commons\/1\/1e\/Symbol_wind_speed_14.svg',\r\n                'https:\/\/upload.wikimedia.org\/wikipedia\/commons\/a\/a7\/Symbol_wind_speed_15.svg',\r\n            ];\r\n\r\n            json_data = {\"atlantic\":[{\"outTemp\":\"54.4\",\"dateTime\":\"1778504220\",\"dewpoint\":\"41.655488382843046\",\"barometer\":\"30.047\",\"rainRate\":\"0\",\"windDir\":\"202.5\",\"windGust\":\"4\",\"windSpeed\":\"3\"},{\"outTemp\":\"54.4\",\"dateTime\":\"1778504160\",\"dewpoint\":\"41.234655800223365\",\"barometer\":\"30.046\",\"rainRate\":\"0\",\"windDir\":\"202.5\",\"windGust\":\"6\",\"windSpeed\":\"5\"}],\"essic\":[{\"outTemp\":\"63.3\",\"dateTime\":\"1778180760\",\"dewpoint\":\"39.19625187394661\",\"barometer\":\"29.838\",\"rainRate\":\"0\",\"windDir\":\"157.5\",\"windGust\":\"2\",\"windSpeed\":\"1\"},{\"outTemp\":\"63.3\",\"dateTime\":\"1778180700\",\"dewpoint\":\"39.19625187394661\",\"barometer\":\"29.835\",\"rainRate\":\"0\",\"windDir\":\"157.5\",\"windGust\":\"2\",\"windSpeed\":\"1\"}],\"golf\":[{\"outTemp\":\"62.6\",\"dateTime\":\"1778180760\",\"dewpoint\":\"42.08430421575363\",\"barometer\":\"29.857\",\"rainRate\":\"0\",\"windDir\":\"337.5\",\"windGust\":\"9\",\"windSpeed\":\"6\"},{\"outTemp\":\"62.6\",\"dateTime\":\"1778180700\",\"dewpoint\":\"43.1686538219318\",\"barometer\":\"29.854\",\"rainRate\":\"0\",\"windDir\":\"337.5\",\"windGust\":\"10\",\"windSpeed\":\"5\"}],\"williams\":[{\"outTemp\":\"52.8\",\"dateTime\":\"1778504220\",\"dewpoint\":\"41.363701150116235\",\"barometer\":\"30.192\",\"rainRate\":\"0\",\"windDir\":\"0\",\"windGust\":\"3\",\"windSpeed\":\"2\"},{\"outTemp\":\"52.8\",\"dateTime\":\"1778504160\",\"dewpoint\":\"40.96295983969199\",\"barometer\":\"30.19\",\"rainRate\":\"0\",\"windDir\":\"0\",\"windGust\":\"3\",\"windSpeed\":\"2\"}],\"vmh\":[{\"outTemp\":\"53.6\",\"dateTime\":\"1778504220\",\"dewpoint\":\"41.313555748144466\",\"barometer\":\"30.158\",\"rainRate\":\"0\",\"windDir\":null,\"windGust\":\"0\",\"windSpeed\":\"0\"},{\"outTemp\":\"53.7\",\"dateTime\":\"1778504160\",\"dewpoint\":\"41.40816269597414\",\"barometer\":\"30.158\",\"rainRate\":\"0\",\"windDir\":null,\"windGust\":\"1\",\"windSpeed\":\"0\"}],\"observ\":[{\"outTemp\":\"50.2\",\"dateTime\":\"1778504220\",\"dewpoint\":\"45.55403660533044\",\"barometer\":\"30.074\",\"rainRate\":\"0\",\"windDir\":null,\"windGust\":\"0\",\"windSpeed\":\"0\"},{\"outTemp\":\"50.3\",\"dateTime\":\"1778504160\",\"dewpoint\":\"45.651964113633824\",\"barometer\":\"30.076\",\"rainRate\":\"0\",\"windDir\":null,\"windGust\":\"0\",\"windSpeed\":\"0\"}],\"chem\":[{\"outTemp\":\"53.5\",\"dateTime\":\"1778504220\",\"dewpoint\":\"41.626483439194985\",\"barometer\":\"30.167\",\"rainRate\":\"0\",\"windDir\":\"292.5\",\"windGust\":\"3\",\"windSpeed\":\"2\"},{\"outTemp\":\"53.5\",\"dateTime\":\"1778504160\",\"dewpoint\":\"42.028443667258635\",\"barometer\":\"30.165\",\"rainRate\":\"0\",\"windDir\":\"292.5\",\"windGust\":\"2\",\"windSpeed\":\"1\"}],\"ches\":[{\"outTemp\":\"53.4\",\"dateTime\":\"1778504220\",\"dewpoint\":\"44.96506806482479\",\"barometer\":\"30.086\",\"rainRate\":\"0\",\"windDir\":null,\"windGust\":\"0\",\"windSpeed\":\"0\"},{\"outTemp\":\"53.4\",\"dateTime\":\"1778504160\",\"dewpoint\":\"44.96506806482479\",\"barometer\":\"30.085\",\"rainRate\":\"0\",\"windDir\":null,\"windGust\":\"0\",\"windSpeed\":\"0\"}]};\r\n\r\n            function circleWithText2(latLng, txt, radius, borderWidth, circleClass, colors) {\r\n                var size = radius * 2;\r\n                var style = 'style=\"width: ' + size + 'px; height: ' + size +\r\n                    'px; border-width: ' + borderWidth +\r\n                    'px; background: rgba('+colors[0]+','+colors[1]+','+colors[2]+', 0.3);' +\r\n                    'border-color: rgba('+colors[0]+','+colors[1]+','+colors[2]+', 1);\"';\r\n                var iconSize = size + (borderWidth * 2);\r\n                var icon = L.divIcon({\r\n                    html: '<span class=\"circle\" id=\"' + circleClass + '\" ' + style + '>' + txt + '<\/span>',\r\n                    className: '',\r\n                    iconSize: [iconSize, iconSize]\r\n                });\r\n                return L.marker(latLng, {icon: icon});\r\n            }\r\n\r\n            var southWest = L.latLng(38.965000, -76.960344),\r\n                northEast = L.latLng(39.004378, -76.920000),\r\n                bounds = L.latLngBounds(southWest, northEast);\r\n\r\n            var map = L.map('map', {\r\n                minZoom: 12,\r\n                bounds: bounds,\r\n                maxBounds: bounds,\r\n                maxBoundsViscosity: .5,\r\n                dragging: window.innerWidth > 768\r\n            }).setView([38.987034, -76.946182], 14);\r\n\r\n            L.tileLayer('https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png', {\r\n                attribution: '&copy; OpenStreetMap'\r\n            }).addTo(map);\r\n\r\n            var maxTemp = 100;\r\n            var minTemp = 0;\r\n\r\n            var stationTitleMap = {\r\n                atlantic: 'Atlantic',\r\n                vmh: 'Van Munching',\r\n                williams: 'AV Williams',\r\n                golf: 'Golf Course',\r\n                chem: 'Chemistry',\r\n                observ: 'Observatory',\r\n                essic: 'ESSIC',\r\n                ches: 'Chesapeake',\r\n            };\r\n\r\n            var stationCoords = {\r\n                'williams': [38.990812, -76.936336],\r\n                'atlantic': [38.991044, -76.941954],\r\n                'vmh': [38.982587, -76.947069],\r\n                'golf': [38.990851, -76.955100],\r\n                'chem': [38.989626, -76.940357],\r\n                'observ': [39.002, -76.956],\r\n                \/\/'avrum': [39.004, -76.942],\r\n                'essic': [38.9709, -76.9219],\r\n                'ches': [38.998, -76.942],\r\n                \/\/'tech': [38.979, -76.925],\r\n            };\r\n\r\n            for (station of Object.keys(stationCoords)) {\r\n\r\n                \/\/ SKIP STATIONS WITH NO DATA\r\n                if (!json_data[station] || json_data[station].length === 0) {\r\n                    console.warn(\"Skipping station due to missing data: \" + station);\r\n                    continue;\r\n                }\r\n\r\n                \/\/ --- robust rounding & display to tenths ---\r\n                \/\/ raw value from JSON\/DB\r\n                var raw = parseFloat(json_data[station][0]['outTemp']);\r\n                \/\/ numeric value for calculations\r\n                var value = Number.isFinite(raw) ? Math.round(raw * 10) \/ 10 : raw;\r\n                \/\/ label always shows one decimal when numeric (e.g. 69.0)\r\n                var label = Number.isFinite(raw) ? (value).toFixed(1) : String(json_data[station][0]['outTemp']);\r\n\r\n                var normValue = (Number.isFinite(value) ? value : 0 - minTemp) \/ (maxTemp - minTemp);\r\n                if (normValue > 1) normValue = 1;\r\n                if (normValue < 0) normValue = 0;\r\n\r\n                windKt = json_data[station][0]['windSpeed'] * 0.868976;\r\n                barbNumber = Math.round(windKt * (16 \/ 75));\r\n\r\n                if (barbNumber > 0) {\r\n                    var iconWidth = 48;\r\n                    var barbIcon = L.icon({\r\n                        iconUrl: barbSymbols[barbNumber],\r\n                        iconSize: [iconWidth, iconWidth],\r\n                        iconAnchor: [iconWidth*(27\/20), iconWidth*(13\/20)],\r\n                    });\r\n                    L.marker(stationCoords[station], {\r\n                        icon: barbIcon,\r\n                        rotationAngle: json_data[station][0]['windDir']\r\n                    }).addTo(map);\r\n                }\r\n\r\n                var marker1 = circleWithText2(\r\n                    stationCoords[station],\r\n                    label,\r\n                    20,\r\n                    1,\r\n                    'circle1',\r\n                    gist_rainbow_r(normValue)\r\n                ).addTo(map);\r\n\r\n                marker1.bindPopup(\r\n                    stationTitleMap[station] +\r\n                    '<br><a href=\"https:\/\/weather.umd.edu\/micronet\/?station=' +\r\n                    station + '\">Link to plotting page<\/a>'\r\n                );\r\n            }\r\n\r\n            var paramString = window.location.href;\r\n            var searchParams = new URLSearchParams(paramString.substring(paramString.indexOf('?')));\r\n            var station = searchParams.get('station');\r\n\r\n            if (!paramString.includes('map') && station == null)\r\n                station = 'atlantic';\r\n\r\n            if (station != null)\r\n                map.setView(stationCoords[station], 18);\r\n\r\n        <\/script>\r\n        \n\n\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":77,"featured_media":0,"parent":7510,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-7601","page","type-page","status-publish","hentry"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/weather.umd.edu\/wordpress\/wp-json\/wp\/v2\/pages\/7601","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/weather.umd.edu\/wordpress\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/weather.umd.edu\/wordpress\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/weather.umd.edu\/wordpress\/wp-json\/wp\/v2\/users\/77"}],"replies":[{"embeddable":true,"href":"https:\/\/weather.umd.edu\/wordpress\/wp-json\/wp\/v2\/comments?post=7601"}],"version-history":[{"count":6,"href":"https:\/\/weather.umd.edu\/wordpress\/wp-json\/wp\/v2\/pages\/7601\/revisions"}],"predecessor-version":[{"id":8227,"href":"https:\/\/weather.umd.edu\/wordpress\/wp-json\/wp\/v2\/pages\/7601\/revisions\/8227"}],"up":[{"embeddable":true,"href":"https:\/\/weather.umd.edu\/wordpress\/wp-json\/wp\/v2\/pages\/7510"}],"wp:attachment":[{"href":"https:\/\/weather.umd.edu\/wordpress\/wp-json\/wp\/v2\/media?parent=7601"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}