diff --git a/includes/openlayers.default_sources.inc b/includes/openlayers.default_sources.inc index 654806dbe0750e374929a823cf8cf0bee8a8a3bb..3c0a295a62f7d03699a9012c9b71e8f96f22045f 100644 --- a/includes/openlayers.default_sources.inc +++ b/includes/openlayers.default_sources.inc @@ -165,23 +165,40 @@ function openlayers_default_sources() { ); $export['source_esri'] = $source; - // Include all "views_geojson_feed" views as sources. - if (module_exists('views_geojson')) { - foreach (views_get_all_views() as $view) { - foreach ($view->display as $display => $data) { - $view->set_display($display); - if ($view->display_handler->get_option('style_plugin') == 'views_geojson_feed') { - $source = new stdClass; - $source->api_version = 1; - $source->machine_name = 'views_geojson_'. $view->name . '_' . $display; - $source->name = 'Views GeoJSON source '. $view->name . '_' . $display; - $source->description = 'This source is automatically generated. See View ' . $view->name . ' at display ' . $display; - $source->class = 'openlayers__source__geojson'; - $source->options = array( - 'url' => url($view->display[$display]->display_options['path'], array('absolute' => TRUE)) - ); - $export[$source->machine_name] = $source; + return $export; +} + +/** + * On behalf of views_geojson. + */ +function views_geojson_default_sources() { + $export = array(); + foreach (views_get_all_views() as $view) { + foreach ($view->display as $display => $data) { + $view->set_display($display); + if (in_array($view->display_handler->get_option('style_plugin'), array('views_geojson_feed', 'views_geojson'))) { + $source = new stdClass(); + $source->api_version = 1; + $source->machine_name = 'views_geojson_' . $view->name . '_' . $display; + $source->name = 'Views GeoJSON source: ' . $view->name . '_' . $display; + $source->description = 'This source is automatically generated. See View ' . $view->name . ' at display ' . $display; + $source->class = 'openlayers__source__geojson'; + + $source->options = array( + 'url' => url($view->display_handler->get_url(), array('absolute' => TRUE)), + ); + + // Determine if we should use a BBox strategy. + if ($arguments = $view->display_handler->get_option('arguments')) { + foreach ($arguments as $id => $argument) { + if (strpos($id, 'bbox') !== FALSE && $argument['default_argument_type'] == 'querystring') { + if (isset($argument['default_argument_options'])) { + $source->options['useBBOX'] = TRUE; + } + } + } } + $export[$source->machine_name] = $source; } } } diff --git a/modules/openlayers_examples/includes/openlayers_examples.default_sources.inc b/modules/openlayers_examples/includes/openlayers_examples.default_sources.inc index de8e2786a88ea625d8d162f26bc733e87a0dbad3..32c6bc1001ad143cf38e9d34b908a2974cbaefbc 100644 --- a/modules/openlayers_examples/includes/openlayers_examples.default_sources.inc +++ b/modules/openlayers_examples/includes/openlayers_examples.default_sources.inc @@ -47,7 +47,7 @@ function openlayers_examples_default_sources() { $source->description = ''; $source->class = 'openlayers__source__geojson'; $source->options = array( - 'url' => url(drupal_get_path('module', 'openlayers_examples') . '/assets/cities.json', array('absolute' => TRUE)), + 'url' => file_create_url(drupal_get_path('module', 'openlayers_examples') . '/assets/cities.json'), ); $export['source_geojson_cities'] = $source; diff --git a/plugins/openlayers/source/openlayers__source__geojson.inc b/plugins/openlayers/source/openlayers__source__geojson.inc index e51cba513843fcf1e79b542d17ac61ea7c5617d2..85eabb5cd3b4bd913e0e4823e54bbeb3bbcfecfc 100644 --- a/plugins/openlayers/source/openlayers__source__geojson.inc +++ b/plugins/openlayers/source/openlayers__source__geojson.inc @@ -5,7 +5,7 @@ function openlayers_openlayers__source__geojson_openlayers_source() { 'handler' => array( 'class' => 'openlayers__source__geojson', 'file' => 'openlayers__source__geojson.inc', - ) + ), ); } @@ -17,5 +17,57 @@ class openlayers__source__geojson extends openlayers_source { '#type' => 'textfield', '#default_value' => $this->getOption('url'), ); + $form['options']['useBBOX'] = array( + '#type' => 'checkbox', + '#title' => t('Use Bounding Box Strategy'), + '#description' => t('Bounding Box strategy will add a query string onto the GeoJSON URL, which means that only data in the viewport of the map will be loaded. This can be helpful if you have lots of data coming from the feed.'), + '#default_value' => $this->getOption('useBBOX'), + ); + //see http://dev.openlayers.org/docs/files/OpenLayers/Strategy/BBOX-js.html#OpenLayers.Strategy.BBOX.resFactor + $form['options']['resFactor'] = array( + '#type' => 'textfield', + '#title' => t('Bounding Box resFactor'), + '#description' => t('Used to determine when previously requested features are invalid (set to 1 if unsure). + The resFactor will be compared to the resolution of the previous request to the current map resolution.
+ If resFactor > (old / new) and 1/resFactor < (old / new). + + '), + '#default_value' => $this->getOption('resFactor', 1), + ); + //see hZttp://dev.openlayers.org/docs/files/OpenLayers/Strategy/BBOX-js.html#OpenLayers.Strategy.BBOX.ratio + $form['options']['ratio'] = array( + '#type' => 'textfield', + '#title' => t('Bounding Box ratio'), + '#description' => t('The ratio of the data bounds to the viewport bounds (in each dimension). Default is 3.'), + '#default_value' => $this->getOption('ratio', 3), + ); + $form['options']['preload'] = array( + '#type' => 'checkbox', + '#title' => t('Preload layer'), + '#description' => t('Load data before layer is made visible. Useful when you want to avoid having to wait for an Ajax call to load the data'), + '#default_value' => $this->getOption('preload', FALSE), + ); + $form['options']['useScript'] = array( + '#type' => 'checkbox', + '#title' => t('Use Script Method'), + '#description' => t('Avoid 405 error and XSS issues load data from another server with ajax'), + '#default_value' => $this->getOption('useScript', FALSE), + ); + $form['options']['callbackKey'] = array( + '#type' => 'textfield', + '#title' => t('Script Callback Key'), + '#description' => t('Key returned by callback along with geoJSON'), + '#default_value' => $this->getOption('callbackKey', NULL), + ); + $form['options']['geojson_data'] = array( + '#type' => 'textarea', + '#title' => t('GeoJSON Data'), + '#description' => t('Paste raw GeoJSON data here. It is better to use a URL. This is provided for very simple use cases like one or two features. If there is data here, it will override the URL above.'), + '#default_value' => $this->getOption('geojson_data'), + ); } } diff --git a/plugins/openlayers/source/openlayers__source__geojson.js b/plugins/openlayers/source/openlayers__source__geojson.js index d9bfef35babe2c1d14169a219a505e3b33cea30a..d8c004d303865a75c9920b558ace270d391d1712 100644 --- a/plugins/openlayers/source/openlayers__source__geojson.js +++ b/plugins/openlayers/source/openlayers__source__geojson.js @@ -1,4 +1,113 @@ Drupal.openlayers.openlayers__source__geojson = function(data) { data.options.projection = 'EPSG:3857'; + + //// If GeoJSON data is provided with the layer, use that. Otherwise + //// check if BBOX, then finally use AJAX method. + //if (data.options.geojson_data) { + // var layer = new ol.Layer.Vector(title, options); + // + // // Read data in. + // features = new ol.Format.GeoJSON(geojson_options).read(data.options.geojson_data); + // if (features) { + // // If not array (ie only one feature) + // if (features.constructor != Array) { + // features = [features]; + // } + // } + // + // // Add features, if needed + // if (features) { + // layer.addFeatures(features); + // layer.events.triggerEvent('loadend'); + // } + //} + //else { + // @todo Add more strategies. Paging strategy would be really interesting + // to use with views_geojson. + if (data.options.useBBOX) { + data.options.format = new ol.format.GeoJSON(); + data.options.strategy = ol.loadingstrategy.bbox; + data.options.loader = function(extent, resolution, projection) { + // Ensure the bbox values are in the correct projection. + var bbox = ol.proj.transformExtent(extent, data.map.getView().getProjection(), 'EPSG:4326'); + + var params = { + 'bbox': bbox.join(','), + 'zoom': data.map.getView().getZoom() + }; + var url = data.options.url; + jQuery(document).trigger('openlayers.bbox_pre_loading', [{'url': url, 'params': params, 'data': data}]); + + var that = this; + jQuery.ajax({ + url: url, + data: params, + success: function(data) { + that.addFeatures(that.readFeatures(data)); + } + }); + }; + var vectorSource = new ol.source.ServerVector(data.options); + return vectorSource; + + ///* + // * We override the triggerRead of the strategy so we can add a zoom=thecurrentzoomlevel in the URL + // * This is used by the geocluster module http://drupal.org/project/geocluster + // */ + //strategy.triggerRead = + // function(options) { + // if (this.response && !(options && data.options.noAbort === true)) { + // this.layer.protocol.abort(this.response); + // this.layer.events.triggerEvent("loadend"); + // } + // this.layer.events.triggerEvent("loadstart"); + // data.options.params = new Array(); + // data.options.params['zoom'] = data.options.object.map.zoom; + // this.response = this.layer.protocol.read( + // ol.Util.applyDefaults({ + // filter: this.createFilter(), + // callback: this.merge, + // scope: this + // }, options)); + // }; + //data.options.strategies = [strategy]; + } + else { + // Fixed strategy. + // @see http://dev.ol.org/releases/OpenLayers-2.12/doc/apidocs/files/OpenLayers/Strategy/Fixed-js.html + if (data.options.preload) { + data.options.strategies = [new ol.Strategy.Fixed({preload: true})]; + } + else { + data.options.strategies = [new ol.Strategy.Fixed()]; + } + } + // if(data.options.useScript){ + // //use Script protocol to get around xss issues and 405 error + // data.options.protocol = new ol.Protocol.Script({ + // url: data.options.url, + // callbackKey: data.options.callbackKey, + // callbackPrefix: "callback:", + // filterToParams: function(filter, params) { + // // example to demonstrate BBOX serialization + // if (filter.type === ol.Filter.Spatial.BBOX) { + // params.bbox = filter.value.toArray(); + // if (filter.projection) { + // params.bbox.push(filter.projection.getCode()); + // } + // } + // return params; + // } + // }); + // } + // else{ + // data.options.protocol = new ol.Protocol.HTTP({ + // url: data.options.url, + // format: new ol.Format.GeoJSON() + // }); + // } + // var layer = new ol.Layer.Vector(title, options); + //} + return new ol.source.GeoJSON(data.options); };