mirror of
https://github.com/mapnik/mapnik.git
synced 2026-01-18 16:27:36 +00:00
Implement sort-by clause parser <field-name>, [DESC | ASC] e.g "name DESC" (default to ASC)
This commit is contained in:
parent
d8acccb636
commit
5d9183fa97
@ -427,7 +427,7 @@ void feature_style_processor<Processor>::prepare_layer(layer_rendering_material&
|
||||
auto sort_by = lay.sort_by();
|
||||
if (sort_by)
|
||||
{
|
||||
q.add_property_name(*sort_by);
|
||||
q.add_property_name((*sort_by).first);
|
||||
}
|
||||
|
||||
bool cache_features = lay.cache_features() && active_styles.size() > 1;
|
||||
@ -502,7 +502,7 @@ void feature_style_processor<Processor>::render_material(layer_rendering_materia
|
||||
{
|
||||
cache->push(feature);
|
||||
}
|
||||
cache->sort_by(*sort_by, true);
|
||||
cache->sort_by((*sort_by).first, (*sort_by).second);
|
||||
std::size_t i = 0;
|
||||
for (feature_type_style const* style : active_styles)
|
||||
{
|
||||
|
||||
@ -27,10 +27,11 @@
|
||||
#include <mapnik/well_known_srs.hpp>
|
||||
#include <mapnik/geometry/box2d.hpp>
|
||||
#include <mapnik/image_compositing.hpp>
|
||||
|
||||
#include <mapnik/util/sort_by.hpp>
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
@ -194,12 +195,12 @@ class MAPNIK_DECL layer
|
||||
/*!
|
||||
* @param column Set the field rendering of this layer is sorted by.
|
||||
*/
|
||||
void set_sort_by(std::string const& column);
|
||||
void set_sort_by(std::string const& column, bool desc = false);
|
||||
|
||||
/*!
|
||||
* @return optional field rendering of this layer is sorted by.
|
||||
* @return optional field (+order) rendering of this layer is sorted by.
|
||||
*/
|
||||
std::optional<std::string> const& sort_by() const;
|
||||
std::optional<sort_by_type> const& sort_by() const;
|
||||
|
||||
/*!
|
||||
* @brief Attach a datasource for this layer.
|
||||
@ -242,7 +243,7 @@ class MAPNIK_DECL layer
|
||||
bool clear_label_cache_;
|
||||
bool cache_features_;
|
||||
std::string group_by_;
|
||||
std::optional<std::string> sort_by_;
|
||||
std::optional<sort_by_type> sort_by_;
|
||||
std::vector<std::string> styles_;
|
||||
std::vector<layer> layers_;
|
||||
datasource_ptr ds_;
|
||||
|
||||
58
include/mapnik/util/sort_by.hpp
Normal file
58
include/mapnik/util/sort_by.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2025 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#ifndef MAPNIK_SORT_BY_HPP
|
||||
#define MAPNIK_SORT_BY_HPP
|
||||
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#include <boost/fusion/include/std_pair.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
using sort_by_type = std::pair<std::string, bool>;
|
||||
|
||||
inline bool parse_sort_by(std::string const& str, sort_by_type & result)
|
||||
{
|
||||
namespace x3 = boost::spirit::x3;
|
||||
auto itr = str.begin();
|
||||
auto end = str.end();
|
||||
auto apply_sort_by = [&](auto const& ctx) {
|
||||
result.first = _attr(ctx);
|
||||
};
|
||||
auto apply_desc = [&](auto const& ctx) {
|
||||
result.second = true;
|
||||
};
|
||||
if (!x3::phrase_parse(itr, end,
|
||||
x3::no_skip[(+x3::char_("a-zA-Z_0-9-"))][apply_sort_by]
|
||||
> -(x3::no_case[x3::lit("DESC")][apply_desc] | x3::no_case[x3::lit("ASC")]),
|
||||
// ASC is a default
|
||||
x3::space
|
||||
) || (itr != end))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mapnik
|
||||
#endif // MAPNIK_SORT_BY_HPP
|
||||
@ -297,12 +297,12 @@ std::string const& layer::group_by() const
|
||||
return group_by_;
|
||||
}
|
||||
|
||||
void layer::set_sort_by(std::string const& column)
|
||||
void layer::set_sort_by(std::string const& column, bool desc)
|
||||
{
|
||||
sort_by_ = column;
|
||||
sort_by_ = {column, desc};
|
||||
}
|
||||
|
||||
std::optional<std::string> const& layer::sort_by() const
|
||||
std::optional<sort_by_type> const& layer::sort_by() const
|
||||
{
|
||||
return sort_by_;
|
||||
}
|
||||
|
||||
@ -49,6 +49,7 @@
|
||||
#include <mapnik/util/dasharray_parser.hpp>
|
||||
#include <mapnik/util/conversions.hpp>
|
||||
#include <mapnik/util/trim.hpp>
|
||||
#include <mapnik/util/sort_by.hpp>
|
||||
#include <mapnik/marker_cache.hpp>
|
||||
#include <mapnik/util/noncopyable.hpp>
|
||||
#include <mapnik/util/fs.hpp>
|
||||
@ -751,10 +752,23 @@ void map_parser::parse_layer(Parent& parent, xml_node const& node)
|
||||
lyr.set_group_by(*group_by);
|
||||
}
|
||||
|
||||
optional<std::string> sort_by = node.get_opt_attr<std::string>("sort-by");
|
||||
if (sort_by)
|
||||
optional<std::string> str = node.get_opt_attr<std::string>("sort-by");
|
||||
if (str)
|
||||
{
|
||||
lyr.set_sort_by(*sort_by);
|
||||
mapnik::sort_by_type result;
|
||||
if (!mapnik::parse_sort_by(*str, result))
|
||||
{
|
||||
std::string s_err("failed to parse Layer sort-by clause \"" + *str + "\"");
|
||||
if (strict_)
|
||||
{
|
||||
throw config_error(s_err);
|
||||
}
|
||||
else
|
||||
{
|
||||
MAPNIK_LOG_ERROR(load_map) << "map_parser: " << s_err;
|
||||
}
|
||||
}
|
||||
lyr.set_sort_by(result.first, result.second);
|
||||
}
|
||||
|
||||
optional<int> buffer_size = node.get_opt_attr<int>("buffer-size");
|
||||
|
||||
@ -549,7 +549,11 @@ void serialize_layer(ptree& map_node, layer const& lyr, bool explicit_defaults)
|
||||
|
||||
if (lyr.sort_by() || explicit_defaults)
|
||||
{
|
||||
set_attr(layer_node, "sort-by", *lyr.sort_by());
|
||||
auto sort_by = *lyr.sort_by();
|
||||
std::string str = sort_by.first;
|
||||
if (sort_by.second)
|
||||
str += " DESC";
|
||||
set_attr(layer_node, "sort-by", str);
|
||||
}
|
||||
|
||||
auto&& buffer_size = lyr.buffer_size();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user