{"action":"created","comment":{"url":"https://api.github.com/repos/LocalGround/localground/pulls/comments/23246732","id":23246732,"diff_hunk":"@@ -0,0 +1,152 @@\n+define(['marionette',\n+        'config',\n+        'underscore',\n+        'lib/maps/overlays/symbolized'\n+    ],\n+    function (Marionette, Config, _, Symbolized) {\n+        'use strict';\n+        /**\n+         * The top-level view class that harnesses all of the map editor\n+         * functionality. Also coordinates event triggers across all of\n+         * the constituent views.\n+         * @class OverlayGroup\n+         */\n+        var Layer = Marionette.ItemView.extend({\n+            /** A google.maps.Map object */\n+            map: null,\n+            dataManager: null,\n+            overlayMap: null,\n+            model: null,\n+            isShowingOnMap: false,\n+            symbols: null,\n+            modelEvents: {\n+                'change:isShowingOnMap': 'redraw',\n+                'symbol-change': 'renderSymbol',\n+                'zoom-to-layer': 'zoomToExtent'\n+            },\n+            initialize: function (opts) {\n+                //console.log(\"initialize Layer!\");\n+                this.app = opts.app;\n+                this.model = opts.model; //a sidepanel LayerItem object\n+                this.dataManager = this.app.dataManager;\n+                this.map = this.app.map;\n+                this.overlayMap = {};\n+                this.parseLayerItem();\n+                this.listenTo(this.app.vent, 'selected-projects-updated', this.parseLayerItem);\n+                this.app.vent.on(\"filter-applied\", this.redraw.bind(this));\n+            },\n+            onBeforeDestroy: function () {\n+                //console.log(\"destroying \", this.model.get(\"name\"));\n+                var that = this;\n+                _.each(this.model.getSymbols(), function (symbol) {\n+                    that.clear(symbol);\n+                });\n+            },\n+            redraw: function () {\n+                if (this.model.get(\"isShowingOnMap\")) {\n+                    this.model.showSymbols();\n+                } else {\n+                    this.model.hideSymbols();\n+                }\n+                this.render();\n+            },\n+            getSymbolOverlays: function (rule) {\n+                return this.overlayMap[rule];\n+            },\n+            getLayerOverlays: function () {\n+                var overlays = [],\n+                    rule;\n+                for (rule in this.overlayMap) {\n+                    overlays = overlays.concat(this.getSymbolOverlays(rule));\n+                }\n+                return overlays;\n+            },\n+            renderSymbol: function (rule) {\n+                _.each(this.getSymbolOverlays(rule), function (overlay) {\n+                    overlay.redraw();\n+                });\n+            },\n+            render: function () {\n+                //console.log(\"rendering \", this.model.get(\"name\"));\n+                var rule;\n+                for (rule in this.overlayMap) {\n+                    this.renderSymbol(rule);\n+                }\n+            },\n+            parseLayerItem: function () {\n+                var that = this;\n+                _.each(this.model.getSymbols(), function (symbol) {\n+                    //clear out old overlays and models\n+                    that.clear(symbol);\n+                    _.each(_.values(that.dataManager.collections), function (collection) {\n+                        that.addMatchingModels(symbol, collection);\n+                    });\n+                });\n+            },\n+            clear: function (symbol) {\n+                symbol.models = [];\n+                this.hideSymbol(symbol.rule);\n+                //once hidden, remove all symbolized map overlay objects for g.c.\n+                this.overlayMap[symbol.rule] = [];\n+            },\n+            addMatchingModels: function (symbol, collection) {\n+                var match = false,\n+                    that = this;\n+                collection.each(function (model) {\n+                    match = symbol.checkModel(model);\n+                    if (match) {\n+                        symbol.addModel(model);\n+                        that.addOverlay(symbol, model);\n+                    }\n+                });\n+            },\n+            addOverlay: function (symbol, model) {\n+                var configKey,\n+                    opts;\n+                if (model.get('geometry') != null) {\n+                    configKey = model.getKey().split(\"_\")[0];\n+                    opts = {\n+                        app: this.app,\n+                        model: model,\n+                        symbol: symbol,\n+                        map: this.map,\n+                        infoBubbleTemplates: {\n+                            InfoBubbleTemplate: _.template(Config[configKey].InfoBubbleTemplate),\n+                            TipTemplate: _.template(Config[configKey].TipTemplate)\n+                        }\n+                    };\n+                    if (this.overlayMap[symbol.rule] == null) {\n+                        this.overlayMap[symbol.rule] = [];\n+                    }\n+                    this.overlayMap[symbol.rule].push(new Symbolized(opts));\n+                }\n+            },\n+\n+            hideSymbol: function (rule) {\n+                var i;\n+                if (!this.overlayMap[rule]) {\n+                    return;\n+                }\n+                for (i = 0; i < this.overlayMap[rule].length; i++) {\n+                    this.overlayMap[rule][i].hide();\n+                }\n+            },\n+\n+\n+            /** Zooms to the extent of the collection */\n+            zoomToExtent: function () {\n+                console.log(\"zoom to extent\");\n+                var bounds = new google.maps.LatLngBounds(),\n+                    i,\n+                    key;\n+                for (key in this.overlayMap) {\n+                    for (i = 0; i < this.overlayMap[key].length; i++) {\n+                        bounds.union(this.overlayMap[key][i].getBounds());\n+                    }\n+                }\n+                this.map.fitBounds(bounds);","path":"static/backbone/js/api/views/maps/overlays/layer.js","position":147,"original_position":147,"commit_id":"d0e8ad0b3b1a93cbcc1719f42b1ad6474cc69fc2","original_commit_id":"d0e8ad0b3b1a93cbcc1719f42b1ad6474cc69fc2","user":{"login":"zmmachar","id":2395896,"avatar_url":"https://avatars.githubusercontent.com/u/2395896?v=3","gravatar_id":"","url":"https://api.github.com/users/zmmachar","html_url":"https://github.com/zmmachar","followers_url":"https://api.github.com/users/zmmachar/followers","following_url":"https://api.github.com/users/zmmachar/following{/other_user}","gists_url":"https://api.github.com/users/zmmachar/gists{/gist_id}","starred_url":"https://api.github.com/users/zmmachar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zmmachar/subscriptions","organizations_url":"https://api.github.com/users/zmmachar/orgs","repos_url":"https://api.github.com/users/zmmachar/repos","events_url":"https://api.github.com/users/zmmachar/events{/privacy}","received_events_url":"https://api.github.com/users/zmmachar/received_events","type":"User","site_admin":false},"body":"If there is nothing matching the overlay, this takes you to the int'l dateline I think","created_at":"2015-01-20T19:12:24Z","updated_at":"2015-01-20T19:12:24Z","html_url":"https://github.com/LocalGround/localground/pull/15#discussion_r23246732","pull_request_url":"https://api.github.com/repos/LocalGround/localground/pulls/15","_links":{"self":{"href":"https://api.github.com/repos/LocalGround/localground/pulls/comments/23246732"},"html":{"href":"https://github.com/LocalGround/localground/pull/15#discussion_r23246732"},"pull_request":{"href":"https://api.github.com/repos/LocalGround/localground/pulls/15"}}},"pull_request":{"url":"https://api.github.com/repos/LocalGround/localground/pulls/15","id":27639015,"html_url":"https://github.com/LocalGround/localground/pull/15","diff_url":"https://github.com/LocalGround/localground/pull/15.diff","patch_url":"https://github.com/LocalGround/localground/pull/15.patch","issue_url":"https://api.github.com/repos/LocalGround/localground/issues/15","number":15,"state":"open","locked":false,"title":"Layers & Filtering","user":{"login":"vanwars","id":1214147,"avatar_url":"https://avatars.githubusercontent.com/u/1214147?v=3","gravatar_id":"","url":"https://api.github.com/users/vanwars","html_url":"https://github.com/vanwars","followers_url":"https://api.github.com/users/vanwars/followers","following_url":"https://api.github.com/users/vanwars/following{/other_user}","gists_url":"https://api.github.com/users/vanwars/gists{/gist_id}","starred_url":"https://api.github.com/users/vanwars/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vanwars/subscriptions","organizations_url":"https://api.github.com/users/vanwars/orgs","repos_url":"https://api.github.com/users/vanwars/repos","events_url":"https://api.github.com/users/vanwars/events{/privacy}","received_events_url":"https://api.github.com/users/vanwars/received_events","type":"User","site_admin":false},"body":"Here's a big pull request. It includes:\r\n1) new Jasmine Testing framework: view tests here: http://(your_domain_name)/static/backbone/js/test/index.html\r\n2) JavaScript filtering\r\n3) Layers\r\n\r\nYou'll need to pip install jsonfield==1.0.0, and do a syncdb for new schema changes. Also, to test Layers, you'll need to create one manually in the API, here:  http://(your_domain_name)/api/0/layers/\r\n\r\nI've attached an image. The JSON format is still up in there air, so there's no JSON validation in the Data API (other than ensuring it's JSON).\r\n![screen shot 2015-01-19 at 2 03 14 pm](https://cloud.githubusercontent.com/assets/1214147/5808593/fed82800-9fe3-11e4-9386-cba08563417e.png)\r\n\r\n","created_at":"2015-01-19T22:05:02Z","updated_at":"2015-01-20T19:12:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a13885a9a8ca1bc4091bb3558611e94c680b63a1","assignee":{"login":"zmmachar","id":2395896,"avatar_url":"https://avatars.githubusercontent.com/u/2395896?v=3","gravatar_id":"","url":"https://api.github.com/users/zmmachar","html_url":"https://github.com/zmmachar","followers_url":"https://api.github.com/users/zmmachar/followers","following_url":"https://api.github.com/users/zmmachar/following{/other_user}","gists_url":"https://api.github.com/users/zmmachar/gists{/gist_id}","starred_url":"https://api.github.com/users/zmmachar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zmmachar/subscriptions","organizations_url":"https://api.github.com/users/zmmachar/orgs","repos_url":"https://api.github.com/users/zmmachar/repos","events_url":"https://api.github.com/users/zmmachar/events{/privacy}","received_events_url":"https://api.github.com/users/zmmachar/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/LocalGround/localground/pulls/15/commits","review_comments_url":"https://api.github.com/repos/LocalGround/localground/pulls/15/comments","review_comment_url":"https://api.github.com/repos/LocalGround/localground/pulls/comments/{number}","comments_url":"https://api.github.com/repos/LocalGround/localground/issues/15/comments","statuses_url":"https://api.github.com/repos/LocalGround/localground/statuses/d0e8ad0b3b1a93cbcc1719f42b1ad6474cc69fc2","head":{"label":"LocalGround:rosa-parks-l13-l14","ref":"rosa-parks-l13-l14","sha":"d0e8ad0b3b1a93cbcc1719f42b1ad6474cc69fc2","user":{"login":"LocalGround","id":2390693,"avatar_url":"https://avatars.githubusercontent.com/u/2390693?v=3","gravatar_id":"","url":"https://api.github.com/users/LocalGround","html_url":"https://github.com/LocalGround","followers_url":"https://api.github.com/users/LocalGround/followers","following_url":"https://api.github.com/users/LocalGround/following{/other_user}","gists_url":"https://api.github.com/users/LocalGround/gists{/gist_id}","starred_url":"https://api.github.com/users/LocalGround/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LocalGround/subscriptions","organizations_url":"https://api.github.com/users/LocalGround/orgs","repos_url":"https://api.github.com/users/LocalGround/repos","events_url":"https://api.github.com/users/LocalGround/events{/privacy}","received_events_url":"https://api.github.com/users/LocalGround/received_events","type":"Organization","site_admin":false},"repo":{"id":5909819,"name":"localground","full_name":"LocalGround/localground","owner":{"login":"LocalGround","id":2390693,"avatar_url":"https://avatars.githubusercontent.com/u/2390693?v=3","gravatar_id":"","url":"https://api.github.com/users/LocalGround","html_url":"https://github.com/LocalGround","followers_url":"https://api.github.com/users/LocalGround/followers","following_url":"https://api.github.com/users/LocalGround/following{/other_user}","gists_url":"https://api.github.com/users/LocalGround/gists{/gist_id}","starred_url":"https://api.github.com/users/LocalGround/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LocalGround/subscriptions","organizations_url":"https://api.github.com/users/LocalGround/orgs","repos_url":"https://api.github.com/users/LocalGround/repos","events_url":"https://api.github.com/users/LocalGround/events{/privacy}","received_events_url":"https://api.github.com/users/LocalGround/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/LocalGround/localground","description":"","fork":false,"url":"https://api.github.com/repos/LocalGround/localground","forks_url":"https://api.github.com/repos/LocalGround/localground/forks","keys_url":"https://api.github.com/repos/LocalGround/localground/keys{/key_id}","collaborators_url":"https://api.github.com/repos/LocalGround/localground/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/LocalGround/localground/teams","hooks_url":"https://api.github.com/repos/LocalGround/localground/hooks","issue_events_url":"https://api.github.com/repos/LocalGround/localground/issues/events{/number}","events_url":"https://api.github.com/repos/LocalGround/localground/events","assignees_url":"https://api.github.com/repos/LocalGround/localground/assignees{/user}","branches_url":"https://api.github.com/repos/LocalGround/localground/branches{/branch}","tags_url":"https://api.github.com/repos/LocalGround/localground/tags","blobs_url":"https://api.github.com/repos/LocalGround/localground/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/LocalGround/localground/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/LocalGround/localground/git/refs{/sha}","trees_url":"https://api.github.com/repos/LocalGround/localground/git/trees{/sha}","statuses_url":"https://api.github.com/repos/LocalGround/localground/statuses/{sha}","languages_url":"https://api.github.com/repos/LocalGround/localground/languages","stargazers_url":"https://api.github.com/repos/LocalGround/localground/stargazers","contributors_url":"https://api.github.com/repos/LocalGround/localground/contributors","subscribers_url":"https://api.github.com/repos/LocalGround/localground/subscribers","subscription_url":"https://api.github.com/repos/LocalGround/localground/subscription","commits_url":"https://api.github.com/repos/LocalGround/localground/commits{/sha}","git_commits_url":"https://api.github.com/repos/LocalGround/localground/git/commits{/sha}","comments_url":"https://api.github.com/repos/LocalGround/localground/comments{/number}","issue_comment_url":"https://api.github.com/repos/LocalGround/localground/issues/comments/{number}","contents_url":"https://api.github.com/repos/LocalGround/localground/contents/{+path}","compare_url":"https://api.github.com/repos/LocalGround/localground/compare/{base}...{head}","merges_url":"https://api.github.com/repos/LocalGround/localground/merges","archive_url":"https://api.github.com/repos/LocalGround/localground/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/LocalGround/localground/downloads","issues_url":"https://api.github.com/repos/LocalGround/localground/issues{/number}","pulls_url":"https://api.github.com/repos/LocalGround/localground/pulls{/number}","milestones_url":"https://api.github.com/repos/LocalGround/localground/milestones{/number}","notifications_url":"https://api.github.com/repos/LocalGround/localground/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/LocalGround/localground/labels{/name}","releases_url":"https://api.github.com/repos/LocalGround/localground/releases{/id}","created_at":"2012-09-22T02:58:05Z","updated_at":"2014-12-11T20:08:28Z","pushed_at":"2015-01-20T06:21:23Z","git_url":"git://github.com/LocalGround/localground.git","ssh_url":"git@github.com:LocalGround/localground.git","clone_url":"https://github.com/LocalGround/localground.git","svn_url":"https://github.com/LocalGround/localground","homepage":null,"size":18668,"stargazers_count":9,"watchers_count":9,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":1,"forks":4,"open_issues":1,"watchers":9,"default_branch":"master"}},"base":{"label":"LocalGround:master","ref":"master","sha":"4660ce5960b57ea0dff065b9a3aa3b38d92f2aa6","user":{"login":"LocalGround","id":2390693,"avatar_url":"https://avatars.githubusercontent.com/u/2390693?v=3","gravatar_id":"","url":"https://api.github.com/users/LocalGround","html_url":"https://github.com/LocalGround","followers_url":"https://api.github.com/users/LocalGround/followers","following_url":"https://api.github.com/users/LocalGround/following{/other_user}","gists_url":"https://api.github.com/users/LocalGround/gists{/gist_id}","starred_url":"https://api.github.com/users/LocalGround/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LocalGround/subscriptions","organizations_url":"https://api.github.com/users/LocalGround/orgs","repos_url":"https://api.github.com/users/LocalGround/repos","events_url":"https://api.github.com/users/LocalGround/events{/privacy}","received_events_url":"https://api.github.com/users/LocalGround/received_events","type":"Organization","site_admin":false},"repo":{"id":5909819,"name":"localground","full_name":"LocalGround/localground","owner":{"login":"LocalGround","id":2390693,"avatar_url":"https://avatars.githubusercontent.com/u/2390693?v=3","gravatar_id":"","url":"https://api.github.com/users/LocalGround","html_url":"https://github.com/LocalGround","followers_url":"https://api.github.com/users/LocalGround/followers","following_url":"https://api.github.com/users/LocalGround/following{/other_user}","gists_url":"https://api.github.com/users/LocalGround/gists{/gist_id}","starred_url":"https://api.github.com/users/LocalGround/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LocalGround/subscriptions","organizations_url":"https://api.github.com/users/LocalGround/orgs","repos_url":"https://api.github.com/users/LocalGround/repos","events_url":"https://api.github.com/users/LocalGround/events{/privacy}","received_events_url":"https://api.github.com/users/LocalGround/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/LocalGround/localground","description":"","fork":false,"url":"https://api.github.com/repos/LocalGround/localground","forks_url":"https://api.github.com/repos/LocalGround/localground/forks","keys_url":"https://api.github.com/repos/LocalGround/localground/keys{/key_id}","collaborators_url":"https://api.github.com/repos/LocalGround/localground/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/LocalGround/localground/teams","hooks_url":"https://api.github.com/repos/LocalGround/localground/hooks","issue_events_url":"https://api.github.com/repos/LocalGround/localground/issues/events{/number}","events_url":"https://api.github.com/repos/LocalGround/localground/events","assignees_url":"https://api.github.com/repos/LocalGround/localground/assignees{/user}","branches_url":"https://api.github.com/repos/LocalGround/localground/branches{/branch}","tags_url":"https://api.github.com/repos/LocalGround/localground/tags","blobs_url":"https://api.github.com/repos/LocalGround/localground/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/LocalGround/localground/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/LocalGround/localground/git/refs{/sha}","trees_url":"https://api.github.com/repos/LocalGround/localground/git/trees{/sha}","statuses_url":"https://api.github.com/repos/LocalGround/localground/statuses/{sha}","languages_url":"https://api.github.com/repos/LocalGround/localground/languages","stargazers_url":"https://api.github.com/repos/LocalGround/localground/stargazers","contributors_url":"https://api.github.com/repos/LocalGround/localground/contributors","subscribers_url":"https://api.github.com/repos/LocalGround/localground/subscribers","subscription_url":"https://api.github.com/repos/LocalGround/localground/subscription","commits_url":"https://api.github.com/repos/LocalGround/localground/commits{/sha}","git_commits_url":"https://api.github.com/repos/LocalGround/localground/git/commits{/sha}","comments_url":"https://api.github.com/repos/LocalGround/localground/comments{/number}","issue_comment_url":"https://api.github.com/repos/LocalGround/localground/issues/comments/{number}","contents_url":"https://api.github.com/repos/LocalGround/localground/contents/{+path}","compare_url":"https://api.github.com/repos/LocalGround/localground/compare/{base}...{head}","merges_url":"https://api.github.com/repos/LocalGround/localground/merges","archive_url":"https://api.github.com/repos/LocalGround/localground/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/LocalGround/localground/downloads","issues_url":"https://api.github.com/repos/LocalGround/localground/issues{/number}","pulls_url":"https://api.github.com/repos/LocalGround/localground/pulls{/number}","milestones_url":"https://api.github.com/repos/LocalGround/localground/milestones{/number}","notifications_url":"https://api.github.com/repos/LocalGround/localground/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/LocalGround/localground/labels{/name}","releases_url":"https://api.github.com/repos/LocalGround/localground/releases{/id}","created_at":"2012-09-22T02:58:05Z","updated_at":"2014-12-11T20:08:28Z","pushed_at":"2015-01-20T06:21:23Z","git_url":"git://github.com/LocalGround/localground.git","ssh_url":"git@github.com:LocalGround/localground.git","clone_url":"https://github.com/LocalGround/localground.git","svn_url":"https://github.com/LocalGround/localground","homepage":null,"size":18668,"stargazers_count":9,"watchers_count":9,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":1,"forks":4,"open_issues":1,"watchers":9,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/LocalGround/localground/pulls/15"},"html":{"href":"https://github.com/LocalGround/localground/pull/15"},"issue":{"href":"https://api.github.com/repos/LocalGround/localground/issues/15"},"comments":{"href":"https://api.github.com/repos/LocalGround/localground/issues/15/comments"},"review_comments":{"href":"https://api.github.com/repos/LocalGround/localground/pulls/15/comments"},"review_comment":{"href":"https://api.github.com/repos/LocalGround/localground/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/LocalGround/localground/pulls/15/commits"},"statuses":{"href":"https://api.github.com/repos/LocalGround/localground/statuses/d0e8ad0b3b1a93cbcc1719f42b1ad6474cc69fc2"}}}}