diff --git a/NAMESPACE b/NAMESPACE index 4b808b1c..cc628c02 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -3,6 +3,7 @@ S3method(findEncodedColumn,default) S3method(findEncodedColumn,sfencoded) S3method(get_box,data.frame) +S3method(get_box,mesh3d) S3method(get_box,quadmesh) S3method(get_box,sf) S3method(get_box,sfencoded) @@ -20,6 +21,7 @@ S3method(normalisesGeojsonData,sf) S3method(print,mapdeck_api) S3method(resolve_data,data.frame) S3method(resolve_data,default) +S3method(resolve_data,mesh3d) S3method(resolve_data,quadmesh) S3method(resolve_data,sf) S3method(resolve_data,sfencoded) diff --git a/R/RcppExports.R b/R/RcppExports.R index ca3dcb45..10279b91 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -73,8 +73,8 @@ rcpp_line_geojson_df <- function(data, params, geometry_columns) { .Call(`_mapdeck_rcpp_line_geojson_df`, data, params, geometry_columns) } -rcpp_mesh_geojson <- function(mesh) { - .Call(`_mapdeck_rcpp_mesh_geojson`, mesh) +rcpp_mesh_geojson <- function(mesh, params, geometry_columns) { + .Call(`_mapdeck_rcpp_mesh_geojson`, mesh, params, geometry_columns) } rcpp_path_geojson <- function(data, params, geometry_columns) { diff --git a/R/map_data.R b/R/map_data.R index 3cb27cd0..84b5227b 100644 --- a/R/map_data.R +++ b/R/map_data.R @@ -145,13 +145,17 @@ sf_needs_subsetting <- function( data, sfc_col, sf_geom ) { } #' @export -resolve_data.quadmesh <- function( data, l, sf_geom ) { +resolve_data.mesh3d <- function( data, l, sf_geom ) { l[["data"]] <- data l[["bbox"]] <- get_box( data, l ) + l[["geometry"]] <- "geometry" l[["data_type"]] <- "mesh" return(l) } +#' @export +resolve_data.quadmesh <- resolve_data.mesh3d + ## use the specificed st_geometry column #' @export resolve_data.sf <- function( data, l, sf_geom ) { @@ -170,8 +174,9 @@ resolve_data.sf <- function( data, l, sf_geom ) { get_box <- function( data, l ) UseMethod("get_box") + #' @export -get_box.quadmesh <- function( data, l ) { +get_box.mesh3d <- function( data, l ) { md <- data[["raster_metadata"]] bbox <- list( c(md[["xmn"]], md[["ymn"]], md[["xmx"]], md[["ymx"]]) @@ -179,6 +184,9 @@ get_box.quadmesh <- function( data, l ) { return( jsonify::to_json( bbox ) ) } +#' @export +get_box.quadmesh <- get_box.mesh3d + #' @export get_box.sfencoded <- function( data, l ) { bbox <- attr( data, "sfAttributes")[["bbox"]] diff --git a/R/map_layer_mesh.R b/R/map_layer_mesh.R index 26b2e875..11cfe4b2 100644 --- a/R/map_layer_mesh.R +++ b/R/map_layer_mesh.R @@ -38,7 +38,7 @@ add_mesh <- function( ) { #if( is.null( stroke_colour )) stroke_colour <- fill_colour - experimental_layer( "mesh" ) + # experimental_layer( "mesh" ) l <- list() l[["fill_colour"]] <- force( fill_colour ) @@ -58,15 +58,15 @@ add_mesh <- function( focus_layer <- force( focus_layer ) is_extruded <- TRUE - if( !is.null( l[["stroke_width"]] ) | !is.null( l[["stroke_colour"]] ) ) { - is_extruded <- FALSE - if( !is.null( elevation ) ) { - message("stroke provided, ignoring elevation") - } - if( is.null( l[["stroke_width"]] ) ) { - l[["stroke_width"]] <- 1L - } - } + # if( !is.null( l[["stroke_width"]] ) | !is.null( l[["stroke_colour"]] ) ) { + # is_extruded <- FALSE + # if( !is.null( elevation ) ) { + # message("stroke provided, ignoring elevation") + # } + # if( is.null( l[["stroke_width"]] ) ) { + # l[["stroke_width"]] <- 1L + # } + # } if ( !is.null(l[["data"]]) ) { data <- l[["data"]] @@ -82,7 +82,7 @@ add_mesh <- function( checkHexAlpha(highlight_colour) layer_id <- layerId(layer_id, "polygon") - map <- addDependency(map, mapdeckPolygonDependency()) + map <- addDependency(map, mapdeckMeshDependency()) tp <- l[["data_type"]] l[["data_type"]] <- NULL @@ -90,10 +90,8 @@ add_mesh <- function( jsfunc <- "add_mesh" if ( tp == "mesh" ) { - - print( "mesh data") - shape <- rcpp_mesh_geojson( data ); - + geometry_column <- c( "geometry" ) + shape <- rcpp_mesh_geojson( data, l, geometry_column ) } # geometry_column <- c( "geometry" ) ## This is where we woudl also specify 'origin' or 'destination' # shape <- rcpp_polygon_geojson( data, l, geometry_column ) @@ -103,6 +101,8 @@ add_mesh <- function( # jsfunc <- "add_polygon_polyline" # } + # return( shape ) + light_settings <- jsonify::to_json(light_settings, unbox = T) js_transitions <- resolve_transitions( transitions, "polygon" ) diff --git a/R/map_layer_polygon.R b/R/map_layer_polygon.R index 9d9e11d6..287bd957 100644 --- a/R/map_layer_polygon.R +++ b/R/map_layer_polygon.R @@ -189,6 +189,7 @@ add_polygon <- function( if ( tp == "sf" ) { geometry_column <- c( "geometry" ) ## This is where we woudl also specify 'origin' or 'destination' + print( l ) shape <- rcpp_polygon_geojson( data, l, geometry_column ) } else if ( tp == "sfencoded" ) { geometry_column <- "polyline" diff --git a/inst/htmlwidgets/lib/mesh/mesh.js b/inst/htmlwidgets/lib/mesh/mesh.js index 8cabad90..91d03f35 100644 --- a/inst/htmlwidgets/lib/mesh/mesh.js +++ b/inst/htmlwidgets/lib/mesh/mesh.js @@ -1,6 +1,8 @@ function add_mesh( map_id, map_type, polygon_data, layer_id, light_settings, auto_highlight, highlight_colour, legend, bbox, update_view, focus_layer, js_transition, is_extruded ) { + + /* class MeshLayer extends PolygonLayer({ calculateFillColors(attribute) { // value is a Uint8ClampedArray @@ -18,15 +20,11 @@ function add_mesh( map_id, map_type, polygon_data, layer_id, light_settings, aut polygon.forEach(ring => { ring.forEach(vertex => { - - - /* const color = ... value[i++] = color[0]; // R value[i++] = color[1]; // G value[i++] = color[2]; // B value[i++] = color[3]; // A - */ }); }); } @@ -34,8 +32,10 @@ function add_mesh( map_id, map_type, polygon_data, layer_id, light_settings, aut }); MeshLayer.layerName = 'MeshLayer'; + */ - const meshLayer = new MeshLayer({ + + const meshLayer = new PolygonLayer({ map_id: map_id, id: 'polygon-'+layer_id, data: polygon_data, @@ -46,9 +46,9 @@ function add_mesh( map_id, map_type, polygon_data, layer_id, light_settings, aut extruded: is_extruded, lineWidthMinPixels: 0, getPolygon: d => md_get_polygon_coordinates( d ), - getLineColor: d => md_hexToRGBA( d.properties.stroke_colour ), + // getLineColor: d => md_hexToRGBA( d.properties.stroke_colour ), getFillColor: d => md_hexToRGBA( d.properties.fill_colour ), - getLineWidth: d => d.properties.stroke_width, + //getLineWidth: d => d.properties.stroke_width, getElevation: d => d.properties.elevation, lightSettings: light_settings, autoHighlight: auto_highlight, @@ -58,6 +58,8 @@ function add_mesh( map_id, map_type, polygon_data, layer_id, light_settings, aut transitions: js_transition || {} }); + console.log( meshLayer ); + if( map_type == "google_map") { md_update_overlay( map_id, 'mesh-'+layer_id, meshLayer ); } else { diff --git a/inst/include/layers/mesh.hpp b/inst/include/layers/mesh.hpp index 37574aa5..1853e8f9 100644 --- a/inst/include/layers/mesh.hpp +++ b/inst/include/layers/mesh.hpp @@ -6,13 +6,13 @@ namespace mapdeck { namespace mesh { -const std::unordered_map< std::string, std::string > mesh_colours({ - { "fill_colour", "fill_opacity" } -}); + const std::unordered_map< std::string, std::string > mesh_colours({ + { "fill_colour", "fill_opacity" } + }); -const Rcpp::StringVector mesh_legend = Rcpp::StringVector::create( - "fill_colour" -); + const Rcpp::StringVector mesh_legend = Rcpp::StringVector::create( + "fill_colour" + ); } // namespace mesh } // namespace mapdeck diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index 9631edcb..eca3d673 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -246,13 +246,15 @@ BEGIN_RCPP END_RCPP } // rcpp_mesh_geojson -Rcpp::List rcpp_mesh_geojson(Rcpp::List mesh); -RcppExport SEXP _mapdeck_rcpp_mesh_geojson(SEXP meshSEXP) { +Rcpp::List rcpp_mesh_geojson(Rcpp::List mesh, Rcpp::List params, std::string geometry_columns); +RcppExport SEXP _mapdeck_rcpp_mesh_geojson(SEXP meshSEXP, SEXP paramsSEXP, SEXP geometry_columnsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< Rcpp::List >::type mesh(meshSEXP); - rcpp_result_gen = Rcpp::wrap(rcpp_mesh_geojson(mesh)); + Rcpp::traits::input_parameter< Rcpp::List >::type params(paramsSEXP); + Rcpp::traits::input_parameter< std::string >::type geometry_columns(geometry_columnsSEXP); + rcpp_result_gen = Rcpp::wrap(rcpp_mesh_geojson(mesh, params, geometry_columns)); return rcpp_result_gen; END_RCPP } @@ -484,7 +486,7 @@ static const R_CallMethodDef CallEntries[] = { {"_mapdeck_rcpp_hexagon_polyline", (DL_FUNC) &_mapdeck_rcpp_hexagon_polyline, 3}, {"_mapdeck_rcpp_line_geojson", (DL_FUNC) &_mapdeck_rcpp_line_geojson, 3}, {"_mapdeck_rcpp_line_geojson_df", (DL_FUNC) &_mapdeck_rcpp_line_geojson_df, 3}, - {"_mapdeck_rcpp_mesh_geojson", (DL_FUNC) &_mapdeck_rcpp_mesh_geojson, 1}, + {"_mapdeck_rcpp_mesh_geojson", (DL_FUNC) &_mapdeck_rcpp_mesh_geojson, 3}, {"_mapdeck_rcpp_path_geojson", (DL_FUNC) &_mapdeck_rcpp_path_geojson, 3}, {"_mapdeck_rcpp_path_polyline", (DL_FUNC) &_mapdeck_rcpp_path_polyline, 3}, {"_mapdeck_rcpp_pointcloud_geojson", (DL_FUNC) &_mapdeck_rcpp_pointcloud_geojson, 3}, diff --git a/src/line-8c06f326.o.tmp b/src/line-8c06f326.o.tmp deleted file mode 100644 index e69de29b..00000000 diff --git a/src/mesh.cpp b/src/mesh.cpp index d18a9f1d..a84ba9ac 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -7,13 +7,13 @@ Rcpp::List mesh_defaults(int n) { return Rcpp::List::create( _["elevation"] = mapdeck::defaults::default_elevation(n), - _["fill_colour"] = mapdeck::defaults::default_fill_colour(n), - _["stroke_colour"] = mapdeck::defaults::default_stroke_colour(n) + _["fill_colour"] = mapdeck::defaults::default_fill_colour(n) + //_["stroke_colour"] = mapdeck::defaults::default_stroke_colour(n) ); } // [[Rcpp::export]] -Rcpp::List rcpp_mesh_geojson( Rcpp::List mesh ) { +Rcpp::List rcpp_mesh_geojson( Rcpp::List mesh, Rcpp::List params, std::string geometry_columns ) { // TODO // convert mesh3d object into a pseudo-sf.data.farme object @@ -21,43 +21,44 @@ Rcpp::List rcpp_mesh_geojson( Rcpp::List mesh ) { Rcpp::NumericMatrix vb = mesh["vb"]; Rcpp::NumericMatrix ib = mesh["ib"]; - Rcpp::NumericMatrix vbt = transpose( vb ); - Rcpp::NumericMatrix ibt = transpose( ib ); + //Rcpp::NumericMatrix vbt = transpose( vb ); + //Rcpp::NumericMatrix ibt = transpose( ib ); // each column of each row of ib gives the row of vb containing coordinates which form the mesh // as we're working with polygons, we can turn the coordinates into list of matrices - size_t n_row = ibt.nrow(); - size_t n_col = ibt.ncol(); + size_t n_row = ib.nrow(); + size_t n_col = ib.ncol(); - Rcpp::List sfc( n_row ); - Rcpp::List z( n_row ); // for creating a list-column of the z attributes + Rcpp::List sfc( n_col ); + Rcpp::List z( n_col ); // for creating a list-column of the z attributes + + Rcpp::NumericVector avg_z( n_col ); size_t i, j; - Rcpp::NumericVector polygon_indeces( n_col ); + Rcpp::NumericVector polygon_indeces( n_row ); Rcpp::NumericVector polygon_coordinates( 4 ); // TODO always 4? - for( i = 0; i < n_row; i++ ) { - polygon_indeces = ibt(i, _); - Rcpp::NumericMatrix a_polygon( n_col, 4 ); // the number of cols of ib teslls us the number of sets of coordinates + for( i = 0; i < n_col; i++ ) { + polygon_indeces = ib(_, i); + Rcpp::NumericMatrix a_polygon( n_row, 4 ); // the number of cols of ib teslls us the number of sets of coordinates Rcpp::List sfg(1); - Rcpp::NumericVector z_values( n_col ); // each 'col' contains the index of the xyz1 coords + Rcpp::NumericVector z_values( n_row ); // each 'col' contains the index of the xyz1 coords - for( j = 0; j < n_col; j++ ) { + for( j = 0; j < n_row; j++ ) { int this_index = polygon_indeces[j]; this_index = this_index - 1; - a_polygon(j, _) = vbt(this_index, _); + a_polygon(j, _) = vb(_, this_index); z_values[ j ] = a_polygon(j, 2); } + avg_z[i] = Rcpp::mean( z_values ); sfg[0] = a_polygon; sfg.attr("class") = Rcpp::CharacterVector::create("XYZM", "POLYGON", "sfg"); sfc[i] = sfg; - //Rcpp::Rcout << "z_values : " << z_values << std::endl; z[i] = z_values; } - //return z; sfc.attr("class") = Rcpp::CharacterVector::create("sfc_POLYGON", "sfc"); @@ -77,47 +78,50 @@ Rcpp::List rcpp_mesh_geojson( Rcpp::List mesh ) { bbox.attr("names") = Rcpp::CharacterVector::create("xmin", "ymin", "xmax", "ymax"); sfc.attr("bbox") = bbox; - // polygons should now be similar in shape to `sfc` objects - //return sfc; - - Rcpp::List z_column(1); - z_column[0] = z; - z_column.attr("class") = "AsIs"; - Rcpp::DataFrame sf = Rcpp::DataFrame::create( - _["geometry"] = sfc - //_["z"] = z_column + Rcpp::List sf = Rcpp::List::create( + _["geometry"] = sfc, + //_["z"] = z, + _["avg_z"] = avg_z ); sf.attr("class") = Rcpp::CharacterVector::create("sf","data.frame"); + + if ( n_col > 0 ) { + Rcpp::IntegerVector nv = Rcpp::seq( 1, n_col ); + sf.attr("row.names") = nv; + } else { + sf.attr("row.names") = Rcpp::IntegerVector(0); + } + sf.attr("sf_column") = "geometry"; - return sf; + //return sf; - // can now create a data.frame of the vbt objc, and this new polygons list, - // where polygons list is the sf_geometry column + Rcpp::DataFrame data = sf; + //return data; + // can now create a data.frame of the vbt objc, and this new polygons list, + // where polygons list is the sf_geometry column - //int data_rows = data.nrows(); + int data_rows = data.nrows(); - //Rcpp::List lst_defaults = polygon_defaults( data_rows ); // initialise with defaults - //std::unordered_map< std::string, std::string > polygon_colours = mapdeck::polygon::polygon_colours; - //Rcpp::StringVector polygon_legend = mapdeck::polygon::polygon_legend; - //Rcpp::StringVector parameter_exclusions = Rcpp::StringVector::create("legend","legend_options","palette","na_colour"); - //return spatialwidget::geojson::to_geojson_mesh( data ); + Rcpp::List lst_defaults = mesh_defaults( data_rows ); // initialise with defaults + std::unordered_map< std::string, std::string > mesh_colours = mapdeck::mesh::mesh_colours; + Rcpp::StringVector mesh_legend = mapdeck::mesh::mesh_legend; + Rcpp::StringVector parameter_exclusions = Rcpp::StringVector::create("legend","legend_options","palette","na_colour"); - /* return spatialwidget::api::create_geojson_downcast( data, params, lst_defaults, - polygon_colours, - polygon_legend, + mesh_colours, + mesh_legend, data_rows, parameter_exclusions, geometry_columns, true // jsonify legend ); - */ + }