ibrierley / slicer_tile_example

Using grid slicing, flutter_map and a vector painter
0 stars 0 forks source link

How to remove Line in Polygon Bound #1

Open nhtlquan opened 2 years ago

nhtlquan commented 2 years ago

I using this example for my project. But my view has redundant vertical and horizontal lines:

image

How to remove it! Thank!!

My code:

   geoJsonIndexCity = GeoJSONVT(
        jsonDecode(dataCityModel),
        GeoJSONVTOptions(
            debug: 0,
            buffer: 0,
            lineMetrics: true,
            indexMaxZoom: 14,
            generateId: false,
            maxZoom: 21,
            indexMaxPoints: 10000000,
            tolerance: 0,
            // 1 is probably ok, 2+ may be odd if you have adjacent polys lined up and gets simplified
            extent: 256.toInt()));
 SliceLayerWidget(
                index: _bloc.geoJsonIndexCity,
                cityID: _bloc.currentCityID,
                typeView: TypeView.city,
                listCityPrice: _bloc.listCityPrice,
              ),
class SliceLayerWidget extends StatefulWidget {
  final GeoJSONVT? index;
  final String? cityID;
  final String? districtID;
  final TypeView? typeView;
  final List<CityPriceModel>? listCityPrice;
  final List<PriceDistrictModel>? listDistrictPrice;

  const SliceLayerWidget({
    Key? key,
    this.index,
    this.cityID,
    this.districtID,
    this.listCityPrice,
    this.listDistrictPrice,
    this.typeView,
  }) : super(key: key);

  @override
  _SliceLayerWidgetState createState() => _SliceLayerWidgetState();
}

class _SliceLayerWidgetState extends State<SliceLayerWidget> {
  @override
  Widget build(BuildContext context) {
    final mapState = MapState.maybeOf(context)!;

    var width = MediaQuery.of(context).size.width * 2.0;
    var height = MediaQuery.of(context).size.height;

    return StreamBuilder<void>(
        stream: mapState.onMoved,
        builder: (BuildContext context, _) {
          var box = SizedBox(
              width: width * 1.25,
              height: height * 1.25,
              child: RepaintBoundary(
                child: CustomPaint(
                  isComplex: true, //Tells flutter to cache the painter.
                  painter: VectorPainter(
                    mapState: mapState,
                    index: widget.index,
                    typeView: widget.typeView,
                    cityID: widget.cityID,
                    zoom: mapState.zoom,
                    districtID: widget.districtID,
                    listCityPrice: widget.listCityPrice,
                    listDistrictPrice: widget.listDistrictPrice,
                    stream: mapState.onMoved,
                  ),
                ),
              ));
          return box;
        });
  }
}
  @override
  void paint(Canvas canvas, Size size) {
    tileState = TileState(mapState, const CustomPoint(256.0, 256.0));
    tileState!.loopOverTiles((i, j, pos, matrix) {
      var tile = index?.getTile(tileState!.getTileZoom().toInt(), i, j);
      final featuresInTile = [];

      if (tile != null && tile.features.isNotEmpty) {
        featuresInTile.addAll(tile.features);
      }
      canvas.save();
      canvas.transform(matrix.storage);
      var myRect = const Offset(0, 0) & const Size(256.0, 256.0);
      canvas.clipRect(myRect);
      batchCallsDraw(featuresInTile, pos, canvas, {});
      canvas.restore();
    });
  }
  void batchCallsDraw(List<dynamic> featuresInTile, PositionInfo pos, Canvas canvas, [Map options = const {}]) {
    for (var feature in featuresInTile) {
      var superPathBound = dartui.Path();
      var superPathBoundSelected = dartui.Path();

      if (feature.type == 3) {
        for (var item in feature.geometry) {
          List<Offset> offsets = [];
          for (var c = 0; c < item.length; c++) {
            offsets.add(Offset(item[c][0].toDouble(), item[c][1].toDouble()));
          }
          var superPathBG = dartui.Path();
          superPathBG.addPolygon(offsets, false);
          if (typeView == TypeView.city) {
            /// cấp city
            if (feature.tags['_id'] == cityID) {
              ///vẽ bound city
              superPathBoundSelected.addPolygon(offsets, false);
            } else {
              superPathBound.addPolygon(offsets, false);
            }
          } else if (typeView == TypeView.district) {
            /// cấp district
            if (feature.tags['city_id'] == cityID) {
              if (districtID != null && feature.tags['district_i'] == districtID) {
                superPathBoundSelected.addPolygon(offsets, false);
              } else {
                superPathBound.addPolygon(offsets, false);
              }
            }
          }
        }
        canvas.drawPath(
            superPathBound,
            defaultStyle
              ..color = Colors.black
              ..strokeWidth = 1
              ..style = PaintingStyle.stroke);
        canvas.drawPath(
            superPathBoundSelected,
            defaultStyle
              ..color = Colors.black
              ..strokeWidth = 1
              ..style = PaintingStyle.stroke);
      }
    }
  }
ibrierley commented 2 years ago

Are they polygons ? If so, they need to be filled, if not, they need to be LineStrings...I'm guessing thats the issue.

ibrierley commented 2 years ago

Btw the latest branch I've been fiddling with is https://github.com/ibrierley/slicer_tile_example/tree/vector_tile When I get chance I'll likely start splitting into several classes and files to tidy it all up, but still just exploring what is feasible atm.

On Thu, Aug 25, 2022 at 10:21 AM nhtlquan @.***> wrote:

I using this example for my project. But my view has redundant vertical and horizontal lines:

[image: image] https://user-images.githubusercontent.com/20571358/186626416-3954cafc-c2fc-4d48-841c-c9b44fdc1f6e.png

How to remove it! Thank!!

My code:

geoJsonIndexCity = GeoJSONVT( jsonDecode(dataCityModel), GeoJSONVTOptions( debug: 0, buffer: 0, lineMetrics: true, indexMaxZoom: 14, generateId: false, maxZoom: 21, indexMaxPoints: 10000000, tolerance: 0, // 1 is probably ok, 2+ may be odd if you have adjacent polys lined up and gets simplified extent: 256.toInt()));

SliceLayerWidget( index: _bloc.geoJsonIndexCity, cityID: _bloc.currentCityID, typeView: TypeView.city, listCityPrice: _bloc.listCityPrice, ), ` class SliceLayerWidget extends StatefulWidget { final GeoJSONVT? index; final String? cityID; final String? districtID; final TypeView? typeView; final List? listCityPrice; final List? listDistrictPrice;

const SliceLayerWidget({ Key? key, this.index, this.cityID, this.districtID, this.listCityPrice, this.listDistrictPrice, this.typeView, }) : super(key: key);

@OverRide https://github.com/OverRide _SliceLayerWidgetState createState() => _SliceLayerWidgetState(); }

class _SliceLayerWidgetState extends State { @OverRide https://github.com/OverRide Widget build(BuildContext context) { final mapState = MapState.maybeOf(context)!;

var width = MediaQuery.of(context).size.width * 2.0;

var height = MediaQuery.of(context).size.height;

return StreamBuilder(

stream: mapState.onMoved,

builder: (BuildContext context, _) {

  var box = SizedBox(

      width: width * 1.25,

      height: height * 1.25,

      child: RepaintBoundary(

        child: CustomPaint(

          isComplex: true, //Tells flutter to cache the painter.

          painter: VectorPainter(

            mapState: mapState,

            index: widget.index,

            typeView: widget.typeView,

            cityID: widget.cityID,

            zoom: mapState.zoom,

            districtID: widget.districtID,

            listCityPrice: widget.listCityPrice,

            listDistrictPrice: widget.listDistrictPrice,

            stream: mapState.onMoved,

          ),

        ),

      ));

  return box;

});

} } `

` @OverRide https://github.com/OverRide void paint(Canvas canvas, Size size) { tileState = TileState(mapState, const CustomPoint(256.0, 256.0)); tileState!.loopOverTiles((i, j, pos, matrix) { var tile = index?.getTile(tileState!.getTileZoom().toInt(), i, j); final featuresInTile = [];

if (tile != null && tile.features.isNotEmpty) {

featuresInTile.addAll(tile.features);

}

canvas.save();

canvas.transform(matrix.storage);

var myRect = const Offset(0, 0) & const Size(256.0, 256.0);

canvas.clipRect(myRect);

batchCallsDraw(featuresInTile, pos, canvas, {});

canvas.restore();

});

} `

` void batchCallsDraw(List featuresInTile, PositionInfo pos, Canvas canvas, [Map options = const {}]) { for (var feature in featuresInTile) { var superPathBound = dartui.Path(); var superPathBoundSelected = dartui.Path();

if (feature.type == 3) {

for (var item in feature.geometry) {

  List<Offset> offsets = [];

  for (var c = 0; c < item.length; c++) {

    offsets.add(Offset(item[c][0].toDouble(), item[c][1].toDouble()));

  }

  var superPathBG = dartui.Path();

  superPathBG.addPolygon(offsets, false);

  if (typeView == TypeView.city) {

    /// cấp city

    if (feature.tags['_id'] == cityID) {

      ///vẽ bound city

      superPathBoundSelected.addPolygon(offsets, false);

    } else {

      superPathBound.addPolygon(offsets, false);

    }

  } else if (typeView == TypeView.district) {

    /// cấp district

    if (feature.tags['city_id'] == cityID) {

      if (districtID != null && feature.tags['district_i'] == districtID) {

        superPathBoundSelected.addPolygon(offsets, false);

      } else {

        superPathBound.addPolygon(offsets, false);

      }

    }

  }

}

canvas.drawPath(

    superPathBound,

    defaultStyle

      ..color = Colors.black

      ..strokeWidth = 1

      ..style = PaintingStyle.stroke);

canvas.drawPath(

    superPathBoundSelected,

    defaultStyle

      ..color = Colors.black

      ..strokeWidth = 1

      ..style = PaintingStyle.stroke);

}

}

} `

— Reply to this email directly, view it on GitHub https://github.com/ibrierley/slicer_tile_example/issues/1, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA5YN5IBIPTUF7TCMHA7QVTV243KNANCNFSM57SKQJEQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

nhtlquan commented 2 years ago

Btw the latest branch I've been fiddling with is https://github.com/ibrierley/slicer_tile_example/tree/vector_tile When I get chance I'll likely start splitting into several classes and files to tidy it all up, but still just exploring what is feasible atm. On Thu, Aug 25, 2022 at 10:21 AM nhtlquan @.> wrote: I using this example for my project. But my view has redundant vertical and horizontal lines: [image: image] https://user-images.githubusercontent.com/20571358/186626416-3954cafc-c2fc-4d48-841c-c9b44fdc1f6e.png How to remove it! Thank!! My code: geoJsonIndexCity = GeoJSONVT( jsonDecode(dataCityModel), GeoJSONVTOptions( debug: 0, buffer: 0, lineMetrics: true, indexMaxZoom: 14, generateId: false, maxZoom: 21, indexMaxPoints: 10000000, tolerance: 0, // 1 is probably ok, 2+ may be odd if you have adjacent polys lined up and gets simplified extent: 256.toInt())); SliceLayerWidget( index: _bloc.geoJsonIndexCity, cityID: _bloc.currentCityID, typeView: TypeView.city, listCityPrice: _bloc.listCityPrice, ), ` class SliceLayerWidget extends StatefulWidget { final GeoJSONVT? index; final String? cityID; final String? districtID; final TypeView? typeView; final List? listCityPrice; final List? listDistrictPrice; const SliceLayerWidget({ Key? key, this.index, this.cityID, this.districtID, this.listCityPrice, this.listDistrictPrice, this.typeView, }) : super(key: key); @OverRide https://github.com/OverRide _SliceLayerWidgetState createState() => _SliceLayerWidgetState(); } class _SliceLayerWidgetState extends State { @OverRide https://github.com/OverRide Widget build(BuildContext context) { final mapState = MapState.maybeOf(context)!; var width = MediaQuery.of(context).size.width 2.0; var height = MediaQuery.of(context).size.height; return StreamBuilder( stream: mapState.onMoved, builder: (BuildContext context, _) { var box = SizedBox( width: width 1.25, height: height 1.25, child: RepaintBoundary( child: CustomPaint( isComplex: true, //Tells flutter to cache the painter. painter: VectorPainter( mapState: mapState, index: widget.index, typeView: widget.typeView, cityID: widget.cityID, zoom: mapState.zoom, districtID: widget.districtID, listCityPrice: widget.listCityPrice, listDistrictPrice: widget.listDistrictPrice, stream: mapState.onMoved, ), ), )); return box; }); } } ` @OverRide <https://github.com/OverRide> void paint(Canvas canvas, Size size) { tileState = TileState(mapState, const CustomPoint(256.0, 256.0)); tileState!.loopOverTiles((i, j, pos, matrix) { var tile = index?.getTile(tileState!.getTileZoom().toInt(), i, j); final featuresInTile = []; if (tile != null && tile.features.isNotEmpty) { featuresInTile.addAll(tile.features); } canvas.save(); canvas.transform(matrix.storage); var myRect = const Offset(0, 0) & const Size(256.0, 256.0); canvas.clipRect(myRect); batchCallsDraw(featuresInTile, pos, canvas, {}); canvas.restore(); }); } void batchCallsDraw(List featuresInTile, PositionInfo pos, Canvas canvas, [Map options = const {}]) { for (var feature in featuresInTile) { var superPathBound = dartui.Path(); var superPathBoundSelected = dartui.Path(); if (feature.type == 3) { for (var item in feature.geometry) { List<Offset> offsets = []; for (var c = 0; c < item.length; c++) { offsets.add(Offset(item[c][0].toDouble(), item[c][1].toDouble())); } var superPathBG = dartui.Path(); superPathBG.addPolygon(offsets, false); if (typeView == TypeView.city) { /// cấp city if (feature.tags['_id'] == cityID) { ///vẽ bound city superPathBoundSelected.addPolygon(offsets, false); } else { superPathBound.addPolygon(offsets, false); } } else if (typeView == TypeView.district) { /// cấp district if (feature.tags['city_id'] == cityID) { if (districtID != null && feature.tags['district_i'] == districtID) { superPathBoundSelected.addPolygon(offsets, false); } else { superPathBound.addPolygon(offsets, false); } } } } canvas.drawPath( superPathBound, defaultStyle ..color = Colors.black ..strokeWidth = 1 ..style = PaintingStyle.stroke); canvas.drawPath( superPathBoundSelected, defaultStyle ..color = Colors.black ..strokeWidth = 1 ..style = PaintingStyle.stroke); } } } — Reply to this email directly, view it on GitHub <#1>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA5YN5IBIPTUF7TCMHA7QVTV243KNANCNFSM57SKQJEQ . You are receiving this because you are subscribed to this thread.Message ID: **@.***>

I using this but same error: Squares appear, the larger the zoom, the more squares appear My geoJson file:

image

Your geoJson file: US_County_Boundaries.json

image
ibrierley commented 2 years ago

The states geoJson are filled polygons, so you need to have a "fill" on the styling.

nhtlquan commented 2 years ago

The states geoJson are filled polygons, so you need to have a "fill" on the styling.

“Fill” where? Can you give more specific instructions?

ibrierley commented 2 years ago

For example in your code where you have your paint ..style = PaintingStyle.stroke it should be ..style = PaintingStyle.fill

nhtlquan commented 2 years ago

For example in your code where you have your paint ..style = PaintingStyle.stroke it should be ..style = PaintingStyle.fill

I know. But I need bound line of polygons. :(

ibrierley commented 2 years ago

If you need a line for the polys, then you would need to change the geojson, so that instead of "type": "Polygon", it has "type": "LineString" for each feature. I may add a geojson method at some point to convert them all as an option, but probably won't be in the very near future.

You could always do a search/replace on the file and substitute Polygon with LineString for the moment.

nhtlquan commented 2 years ago

ECFA3F08-E6D8-4D58-B108-857BAD177247

This geojson file example open github. Don”t have square line.

ibrierley commented 2 years ago

That one is drawn with "fill"s.

ibrierley commented 2 years ago

The way tile slicers work, is they have to slice each poly/line into "tiles" for performance.

Now, for polys (which are filled), it has to recreate a smaller tile polygon, which is the bit that you are seeing. That would normally be filled, so you wouldn't notice any strange lines for each tile.

LineStrings are treated differently, as it doesn't need to recreate the tile edges to fill in.

nhtlquan commented 2 years ago

That one is drawn with "fill"s.

Yes. I understand. I will try to change from type : multipolygons to type : LineStrings