sublayers of sublayers

Hi, I am currently using syncfusion_flutter_maps 20.2.44 package.


I wish to display 3 levels of administrative units. each one should appear after a certain level of zoom. I could handle for 2 levels of administrative units. The one at the top is the layer the second is the sublayer. But difficult to display the third one.  If SFMaps had the option of sublayer within a sublayer I would have solved that problem.

Thanks for your help, and thanks so much for SFMaps


7 Replies

SK Sriram Kiran Senthilkumar Syncfusion Team August 17, 2022 12:43 PM UTC

Hi Ekani,


Greetings from Syncfusion.


We have checked your query at our end, and we would like to let you know that currently, there is no option for adding a sublayer within a sublayer. However, as the `sublayers` is a list, you can achieve your requirement by dynamically adding and removing the sublayer to/from the collection based on the zoom level. We have also achieved your requirement in a simple sample in which we have a base tile layer (World-map) whose sublayers consist of one shape sublayer (Africa) and when the zoom level reaches 3, another shape sublayer (Egypt) is added. We have attached the sample below for your reference. Please check and get back to us if you require further assistance.


Regards,

Sriram Kiran


Attachment: f176867_792cc006.zip


EM EKANI MEBENGA Thibaut Aloys August 18, 2022 10:33 AM UTC

Dear Kiran,

Thank you so much. I can now add a third layer. 

The sublayers are supposed to appear (when zoomin in) or disappear (when zooming out)  one after the other. It works well when zooming in.But when zooming out, it work sometimes and sometimes all layers appears, at the minzoom level, at the same time.


Kind regards,




SK Sriram Kiran Senthilkumar Syncfusion Team August 19, 2022 12:48 PM UTC

Hi Ekani,


We have checked your query at our end, and we tried to replicate the reported issue in our previously provided sample regarding when zooming out, all the layers appear at the minZoomlevel at the same time, but it didn’t reproduce at our end. So, we kindly request you to share a screen recording of the reported issue and if possible, please modify the sample as per your requirement to replicate the issue, which will help us to assist you in a better way.


Regards,

Sriram Kiran


Attachment: f176867_761f33bf.zip


EM EKANI MEBENGA Thibaut Aloys August 21, 2022 02:15 AM UTC

Hi Kiran,


I could solve the problem with zooming out. Thanks a lot.


Now I have another problem. I wish to show data lable of the first layer at a certain level of zoom, like this :


showDataLabels:_zoomPanBehavior.zoomLevel<1.0?false:true,


It doe not work. hereafter is my entire code.



TooltipAdmin _tooltipAdmin=TooltipAdmin();




class HomeScreen extends StatefulWidget {
const HomeScreen({super.key,
required this.regionsList,
required this.divisionsList,
required this.subdivisionsList,
required this.regionFeatureData,
required this.divisionFeatureData,
required this.subdivisionFeatureData
});

final List regionsList;
final List divisionsList;
final List subdivisionsList;
final List regionFeatureData;
final List divisionFeatureData;
final List subdivisionFeatureData;


@override
State createState() => _HomeScreenState();
}

class _HomeScreenState extends State {

//late List data;

late MapShapeSource _dataSourceRegions;
late MapZoomPanBehavior _zoomPanBehavior;
late List _sublayers;


late MapShapeSource _sublayerSourceDivisions;
late MapShapeSource _sublayerSourceSubdivisions;
late MapZoomDetails detail;
late double myZoomLevel = 1.0;
late bool showDataLabelRegion=true;
late bool showDataLabelDivision=false;
late bool showDataLabelSubdivision= true;
late Widget Function (BuildContext, int) _layerRegionTooltipBuilder ;
late Widget Function (BuildContext, int) _sublayerDivisionTooltipBuilder ;
late Widget Function (BuildContext, int) _sublayerSubdivisionTooltipBuilder ;
Color strokeColorSublayer=Colors.transparent;
double strokeWidthSublayer= 0.0;



// function for selecting the base layer

// function for selecting sublayer

@override
void initState() {


_dataSourceRegions = MapShapeSource.asset(
'assets/regions.json',
shapeDataField: 'province',
dataCount: widget.regionsList.length,
primaryValueMapper: (int index) => widget.regionsList[index].region,
shapeColorValueMapper: (int index) => widget.regionsList[index].color1,

);

_sublayerSourceDivisions = MapShapeSource.asset(
'assets/divisions.json',
shapeDataField: 'division',
dataCount: widget.divisionsList.length,
primaryValueMapper: (int index) => widget.divisionsList[index].division,
shapeColorValueMapper: (int index) => widget.divisionsList[index].color2,

);
_sublayerSourceSubdivisions = MapShapeSource.asset(
'assets/subdivisions.json',
shapeDataField: 'subdivision',
dataCount: widget.subdivisionsList.length,
primaryValueMapper: (int index) =>
widget.subdivisionsList[index].subdivision,

);

_zoomPanBehavior = MapZoomPanBehavior(
maxZoomLevel: 100,
zoomLevel: myZoomLevel,
minZoomLevel: 1,
showToolbar: true,
enablePanning: true,
enablePinching: true,
//toolbarSettings: ,
enableDoubleTapZooming: true, enableMouseWheelZooming: true,

);

_layerRegionTooltipBuilder= (BuildContext context, int index) {

return _selectTooltipRegion(index);
} ;

_sublayerDivisionTooltipBuilder= (BuildContext context, int index) {

return _selectTooltipDivision(index);
} ;

_sublayerSubdivisionTooltipBuilder= (BuildContext context, int index) {

return _selectTooltipSubdivision(index);
} ;


_sublayers = [

];


super.initState();
}



@override
void dispose() {
_sublayers.clear();
super.dispose();
}



final MapShapeLayerController _layerController= MapShapeLayerController();


@override
Widget build(BuildContext context) {

//print(widget.subdivisionFeatureData[1]["properties"]["health_center"]);

//print(widget.subdivisionsList.length);
double viewWidth = MediaQuery.of(context).size.width;
double viewHeight = MediaQuery.of(context).size.height;
print("the zoomlevel is: ${ _zoomPanBehavior.zoomLevel}");

return Scaffold(
body: Stack(

children: [

Padding(
padding: EdgeInsets.symmetric(horizontal: viewWidth * 0.02,
vertical: 0.02 * viewHeight,
),
child: Center(
child: SfMaps(

layers: [
MapShapeLayer(
// TODO: add a variable Tooltip

source: _sublayerSourceDivisions,
controller: _layerController,
strokeColor: Colors.red,
strokeWidth: 1,
showDataLabels:_zoomPanBehavior.zoomLevel<1.0?false:true,
dataLabelSettings: const MapDataLabelSettings(
textStyle: TextStyle(

color:Colors.redAccent,
fontSize: 12,
fontWeight: FontWeight.bold,
//fontStyle: FontStyle.italic,
//fontFamily: 'Times',
),

),
zoomPanBehavior: _zoomPanBehavior,
onWillZoom: _handleOnWillZoom,
shapeTooltipBuilder: _zoomPanBehavior.zoomLevel>1? _sublayerDivisionTooltipBuilder:null,
tooltipSettings: const MapTooltipSettings(
//hideDelay:double.infinity ,
color: Colors.blueAccent,
strokeColor: Color.fromRGBO(252, 187, 15, 1),
strokeWidth: 1.5),

loadingBuilder: (BuildContext context) {
return const SizedBox(
height: 25,
width: 25,
child: CircularProgressIndicator(
strokeWidth: 3,
),
);
},
sublayers:_zoomPanBehavior.zoomLevel==1?[MapShapeSublayer(
source:_dataSourceRegions,
showDataLabels: _zoomPanBehavior.zoomLevel<=2?true:false,
shapeTooltipBuilder:_zoomPanBehavior.zoomLevel<=1? _layerRegionTooltipBuilder:null,
// color: Colors.transparent,
dataLabelSettings: const MapDataLabelSettings(
textStyle: TextStyle(
color: Colors.black,
fontSize:18,
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic,
//fontFamily: 'Times',
),
),
strokeColor:Colors.white,
strokeWidth: 1.2,
)

]: _sublayers,
),

],
),
),
),

],
),
);
}









bool _handleOnWillZoom(MapZoomDetails details) {

// setState(() {
// _zoomPanBehavior.zoomLevel=details.newZoomLevel!;
//
// });

if ( details.newZoomLevel! >1 && details.newZoomLevel! <= 2 ) {



setState(() {
_sublayers.clear();
});


}
else if ( details.newZoomLevel! > 2 ) {

if(_sublayers.isEmpty) {

setState(() {

_sublayers.add(
MapShapeSublayer(
source: _sublayerSourceSubdivisions,
showDataLabels: true,
shapeTooltipBuilder: _sublayerSubdivisionTooltipBuilder,
color: Colors.transparent,
dataLabelSettings: const MapDataLabelSettings(
textStyle: TextStyle(
color: Colors.black,
fontSize: 12,
//fontWeight: FontWeight.bold,
//fontStyle: FontStyle.italic,
//fontFamily: 'Times',
),

),
strokeColor: Colors.black,
strokeWidth: 0.3,
),);
});

}

else if (_sublayers.length>1) {

setState(() {
_sublayers.removeAt(0);

});



}

}

// else if (details.newZoomLevel! <1){
//
// setState(() {
// _sublayers.clear();
// });
//
// }

return true;
}


Widget _selectTooltipDivision(index) {
return _tooltipAdmin.divisionTooltip(
context: context,
adminUnit: "${widget.divisionFeatureData[index]['properties']['division']}",
area: widget.divisionFeatureData[index]["properties"]["area"],
chefLieu: "${widget.divisionFeatureData[index]['properties']['chef_lieu']}",
regionName: "${widget.divisionFeatureData[index]['properties']['region']}",

);
}

Widget _selectTooltipRegion(index) {
return _tooltipAdmin.regionTooltip(
context: context,
//adminUnit: "aaa",
adminUnit: "${widget.regionFeatureData[index]["properties"]["province"]}",
area: widget.regionFeatureData[index]["properties"]["area"],

);
}


Widget _selectTooltipSubdivision(index) {
return _tooltipAdmin.subdivisionTooltip(
context: context,
adminUnit: "${widget.subdivisionFeatureData[index]['properties']['subdivision']}",
area: widget.subdivisionFeatureData[index]["properties"]["area"],
schools:widget.subdivisionFeatureData[index]["properties"]["schools"] ,
nurseryPrimary: widget.subdivisionFeatureData[index]["properties"]["nursery_and_primary"],
nurserySecondary:widget.subdivisionFeatureData[index]["properties"]["nursery_and_secondary"],
nurseryPrimarySecondaryUniversityProfessional: widget.subdivisionFeatureData[index]["properties"]
["nursery_and_primary_and_secondary_and_university_and_profession"],
primarySecondary:widget.subdivisionFeatureData[index]["properties"]["primary_and_secondary"] ,
secondary: widget.subdivisionFeatureData[index]["properties"]["secondary"] ,
universityHigherInstitute: widget.subdivisionFeatureData[index]["properties"]["university_and_higher_institute"],
professional:widget.subdivisionFeatureData[index]["properties"]["professional_and_school"],
healthCenter:widget.subdivisionFeatureData[index]["properties"]["health_center"] ,
population: 3000,
divisionName: "${widget.subdivisionFeatureData[index]['properties']['division']}",

);
}
Besides, I wish to know if one can can add an offline tile layer, for instance a downloaded tiele layer, that is already in te memory.




Kind regards,



SK Sriram Kiran Senthilkumar Syncfusion Team August 22, 2022 02:49 PM UTC

Hi Ekani,


We can reproduce the issue at our end, and we are checking the issue at the source level. We will update further details in one business day, and we appreciate your patience until then.


Regards,
Sriram Kiran



SK Sriram Kiran Senthilkumar Syncfusion Team August 23, 2022 03:07 PM UTC

Hi Ekani,


We considered the reported issue as a bug and created a feedback report “Data labels are not rendered when enabling it programmatically and you can track this issue status using the following link.


https://www.syncfusion.com/feedback/37232


We will include this fix in our Volume 3 main release, which is scheduled for the end of September. We will let you know once the release gets rolled out. We appreciate your patience until then.


Regards,

Sriram Kiran



SK Sriram Kiran Senthilkumar Syncfusion Team September 29, 2022 02:46 PM UTC

Hi Ekani,


We are glad to announce that our Essential Studio 2022 Volume 3 release v20.3.0.47 is rolled out and is available for download under the following link.

Essential Studio 2022 Volume 3 Main Release v20.3.0.47 is available for download | Announcements Forums | Syncfusion


The reported issue regarding the “Data labels are not rendered when enabling it programmatically” is now fixed and rolled out in this release. So, kindly please upgrade the slider package version to the latest version below to overcome the issue.

https://pub.dev/packages/syncfusion_flutter_maps/versions/20.3.47

We thank you for your support and appreciate your patience in waiting for this release. Please get in touch with us if you require any further assistance.


Regards,

Sriram Kiran


Loader.
Up arrow icon