@@ -82,8 +82,10 @@ namespace mapnik
8282 void ensure_font_face ( const text_symbolizer & text_symbol );
8383
8484 bool strict_;
85+ std::map<std::string,parameters> datasource_templates_;
8586 freetype_engine font_engine_;
8687 face_manager<freetype_engine> font_manager_;
88+ std::map<std::string,std::string> file_sources_;
8789 };
8890
8991 void load_map (Map & map, std::string const & filename, bool strict)
@@ -143,6 +145,38 @@ namespace mapnik
143145
144146 parse_layer (map, v.second );
145147 }
148+ else if (v.first == " FileSource" )
149+ {
150+ std::string name = get_attr<string>( v.second , " name" );
151+ std::string value = get_own<string>( v.second , " " );
152+ file_sources_[name] = value;
153+ }
154+ else if (v.first == " Datasource" )
155+ {
156+ std::string name = get_attr (v.second , " name" , string (" Unnamed" ));
157+ parameters params;
158+ ptree::const_iterator paramIter = v.second .begin ();
159+ ptree::const_iterator endParam = v.second .end ();
160+ for (; paramIter != endParam; ++paramIter)
161+ {
162+ ptree const & param = paramIter->second ;
163+
164+ if (paramIter->first == " Parameter" )
165+ {
166+ std::string name = get_attr<string>(param, " name" );
167+ std::string value = get_own<string>( param,
168+ " datasource parameter" );
169+ params[name] = value;
170+ }
171+ else if ( paramIter->first != " <xmlattr>" )
172+ {
173+ throw config_error (std::string (" Unknown child node in " ) +
174+ " 'Datasource'. Expected 'Parameter' but got '" +
175+ paramIter->first + " '" );
176+ }
177+ }
178+ datasource_templates_[name] = params;
179+ }
146180 else if (v.first != " <xmlcomment>" &&
147181 v.first != " <xmlattr>" )
148182 {
@@ -233,6 +267,14 @@ namespace mapnik
233267 else if (child.first == " Datasource" )
234268 {
235269 parameters params;
270+ optional<std::string> base = get_opt_attr<std::string>( child.second , " base" );
271+ if ( base )
272+ {
273+ std::map<std::string,parameters>::const_iterator base_itr = datasource_templates_.find (*base);
274+ if (base_itr!=datasource_templates_.end ())
275+ params = base_itr->second ;
276+ }
277+
236278 ptree::const_iterator paramIter = child.second .begin ();
237279 ptree::const_iterator endParam = child.second .end ();
238280 for (; paramIter != endParam; ++paramIter)
@@ -246,7 +288,7 @@ namespace mapnik
246288 " datasource parameter" );
247289 params[name] = value;
248290 }
249- else
291+ else if ( paramIter-> first != " <xmlattr> " )
250292 {
251293 throw config_error (std::string (" Unknown child node in " ) +
252294 " 'Datasource'. Expected 'Parameter' but got '" +
@@ -400,6 +442,7 @@ namespace mapnik
400442 try
401443 {
402444 optional<std::string> file = get_opt_attr<string>(sym, " file" );
445+ optional<std::string> base = get_opt_attr<string>(sym, " base" );
403446 optional<std::string> type = get_opt_attr<string>(sym, " type" );
404447 optional<boolean> allow_overlap =
405448 get_opt_attr<boolean>(sym, " allow_overlap" );
@@ -411,12 +454,20 @@ namespace mapnik
411454 {
412455 try
413456 {
414- point_symbolizer symbol (*file,*type,*width,*height);
415- if (allow_overlap)
416- {
417- symbol.set_allow_overlap ( * allow_overlap );
418- }
419- rule.append (symbol);
457+ if ( base )
458+ {
459+ std::map<std::string,std::string>::const_iterator itr = file_sources_.find (*base);
460+ if (itr!=file_sources_.end ())
461+ {
462+ *file = itr->second + " /" + *file;
463+ }
464+ }
465+ point_symbolizer symbol (*file,*type,*width,*height);
466+ if (allow_overlap)
467+ {
468+ symbol.set_allow_overlap ( * allow_overlap );
469+ }
470+ rule.append (symbol);
420471 }
421472 catch (ImageReaderException const & ex )
422473 {
@@ -460,13 +511,22 @@ namespace mapnik
460511 try
461512 {
462513 std::string file = get_attr<string>(sym, " file" );
514+ optional<std::string> base = get_opt_attr<string>(sym, " base" );
463515 std::string type = get_attr<string>(sym, " type" );
464516 unsigned width = get_attr<unsigned >(sym, " width" );
465517 unsigned height = get_attr<unsigned >(sym, " height" );
466518
467519 try
468520 {
469- rule.append (line_pattern_symbolizer (file,type,width,height));
521+ if ( base )
522+ {
523+ std::map<std::string,std::string>::const_iterator itr = file_sources_.find (*base);
524+ if (itr!=file_sources_.end ())
525+ {
526+ file = itr->second + " /" + file;
527+ }
528+ }
529+ rule.append (line_pattern_symbolizer (file,type,width,height));
470530 }
471531 catch (ImageReaderException const & ex )
472532 {
@@ -495,12 +555,21 @@ namespace mapnik
495555 try
496556 {
497557 std::string file = get_attr<string>(sym, " file" );
558+ optional<std::string> base = get_opt_attr<string>(sym, " base" );
498559 std::string type = get_attr<string>(sym, " type" );
499560 unsigned width = get_attr<unsigned >(sym, " width" );
500561 unsigned height = get_attr<unsigned >(sym, " height" );
501562
502563 try
503564 {
565+ if ( base )
566+ {
567+ std::map<std::string,std::string>::iterator itr = file_sources_.find (*base);
568+ if (itr!=file_sources_.end ())
569+ {
570+ file = itr->second + " /" + file;
571+ }
572+ }
504573 rule.append (polygon_pattern_symbolizer (file,type,width,height));
505574 }
506575 catch (ImageReaderException const & ex )
@@ -631,15 +700,24 @@ namespace mapnik
631700 Color fill = get_attr (sym, " fill" , Color (0 ,0 ,0 ));
632701
633702 std::string image_file = get_attr<string>(sym, " file" );
703+ optional<std::string> base = get_opt_attr<string>(sym, " base" );
634704 std::string type = get_attr<string>(sym, " type" );
635705 unsigned width = get_attr<unsigned >(sym, " width" );
636706 unsigned height = get_attr<unsigned >(sym, " height" );
637707
638708 try
639709 {
710+ if ( base )
711+ {
712+ std::map<std::string,std::string>::const_iterator itr = file_sources_.find (*base);
713+ if (itr!=file_sources_.end ())
714+ {
715+ image_file = itr->second + " /" + image_file;
716+ }
717+ }
640718 shield_symbolizer shield_symbol (name,face_name,size,fill,
641- image_file,type,width,height);
642-
719+ image_file,type,width,height);
720+
643721 // minimum distance between labels
644722 optional<unsigned > min_distance =
645723 get_opt_attr<unsigned >(sym, " min_distance" );
@@ -651,18 +729,18 @@ namespace mapnik
651729 }
652730 catch (ImageReaderException const & ex )
653731 {
654- string msg (" Failed to load image file '" + image_file +
732+ string msg (" Failed to load image file '" + image_file +
655733 " ': " + ex.what ());
656- if (strict_)
657- {
658- throw config_error (msg);
659- }
660- else
661- {
662- clog << " ### WARNING: " << msg << endl;
663- }
734+ if (strict_)
735+ {
736+ throw config_error (msg);
737+ }
738+ else
739+ {
740+ clog << " ### WARNING: " << msg << endl;
741+ }
664742 }
665-
743+
666744 }
667745 catch (const config_error & ex)
668746 {
0 commit comments