From ac983e76310820e76f14aee8ee31175cb5eba693 Mon Sep 17 00:00:00 2001
From: thinkinggis <lzx199065@gmail.com>
Date: Tue, 19 Nov 2019 10:21:43 +0800
Subject: [PATCH] refactor(layer): point,polygon line model

---
 examples/gallery/basic/demo/arcCircle.js      |   4 +-
 examples/gallery/basic/demo/column_dark.js    |   4 +-
 examples/gallery/basic/demo/normal.js         |   4 +-
 examples/gallery/basic/demo/point.js          |   4 +-
 examples/line/arc/demo/arc.js                 |  10 +-
 examples/line/arc/demo/arcCircle.js           |  41 +++---
 examples/line/arc/demo/trip_arc.js            |   7 +-
 examples/line/arc/demo/trip_arc_dark.js       |   6 +-
 examples/point/bubble/demo/color.js           |   2 +-
 examples/point/bubble/demo/meta.json          |  18 +--
 examples/point/bubble/demo/point.js           |   2 +-
 .../point/{scatter => bubble}/demo/scatter.js |   0
 examples/point/bubble/demo/world.js           |   3 +-
 examples/point/column/demo/clumn_shape.js     |  16 +--
 .../point/column/demo/clumn_shape_light.js    |  18 +--
 examples/point/column/demo/column_dark.js     |  18 +--
 examples/point/column/demo/column_light.js    |  14 +-
 examples/point/image/demo/image.js            |  34 ++---
 examples/point/image/demo/locate.js           |  18 ++-
 examples/point/image/demo/weather.js          |   8 +-
 examples/point/scatter/demo/meta.json         |   7 +-
 examples/point/scatter/demo/normal.js         |   4 +-
 .../normal.js => scatter/demo/normal2.js}     |   4 +-
 examples/polygon/3d/demo/polygon.js           |   6 +-
 .../core/src/services/layer/ILayerService.ts  |  21 ++-
 packages/layers/src/core/BaseLayer.ts         |  23 ++--
 packages/layers/src/core/baseModel.ts         |  55 ++++++++
 packages/layers/src/core/triangulation.ts     |  15 +-
 packages/layers/src/index.ts                  |  19 +--
 packages/layers/src/line/index.ts             | 129 ++----------------
 packages/layers/src/line/{ => models}/arc.ts  |  67 ++++-----
 .../src/line/{arc3d.ts => models/arc_3d.ts}   |  62 ++++-----
 packages/layers/src/line/models/dash.ts       |  22 +++
 .../line/{arc2d.ts => models/great_circle.ts} |  70 ++++------
 packages/layers/src/line/models/index.ts      |  15 ++
 packages/layers/src/line/models/line.ts       | 120 ++++++++++++++++
 .../layers/src/point/buffers/ExtrudeBuffer.ts |  79 -----------
 .../layers/src/point/buffers/ImageBuffer.ts   |  22 ---
 packages/layers/src/point/index.ts            |  57 ++++++--
 .../layers/src/point/{ => models}/extrude.ts  |  60 ++++----
 .../layers/src/point/{ => models}/fill.ts     |  75 ++++------
 .../layers/src/point/{ => models}/image.ts    |  78 ++++-------
 packages/layers/src/point/models/index.ts     |  17 +++
 .../layers/src/point/{ => models}/normal.ts   |  64 +++------
 packages/layers/src/point/models/text.ts      |  30 ++++
 packages/layers/src/polygon/index.ts          |  41 ++----
 packages/layers/src/polygon/models/extrude.ts |  92 +++++++++++++
 packages/layers/src/polygon/models/fill.ts    |  47 +++++++
 packages/layers/src/polygon/models/index.ts   |  11 ++
 packages/layers/src/polygon/polygon3D.ts      |   8 +-
 50 files changed, 829 insertions(+), 722 deletions(-)
 rename examples/point/{scatter => bubble}/demo/scatter.js (100%)
 rename examples/point/{bubble/demo/normal.js => scatter/demo/normal2.js} (90%)
 create mode 100644 packages/layers/src/core/baseModel.ts
 rename packages/layers/src/line/{ => models}/arc.ts (58%)
 rename packages/layers/src/line/{arc3d.ts => models/arc_3d.ts} (58%)
 create mode 100644 packages/layers/src/line/models/dash.ts
 rename packages/layers/src/line/{arc2d.ts => models/great_circle.ts} (58%)
 create mode 100644 packages/layers/src/line/models/index.ts
 create mode 100644 packages/layers/src/line/models/line.ts
 delete mode 100644 packages/layers/src/point/buffers/ExtrudeBuffer.ts
 delete mode 100644 packages/layers/src/point/buffers/ImageBuffer.ts
 rename packages/layers/src/point/{ => models}/extrude.ts (68%)
 rename packages/layers/src/point/{ => models}/fill.ts (61%)
 rename packages/layers/src/point/{ => models}/image.ts (58%)
 create mode 100644 packages/layers/src/point/models/index.ts
 rename packages/layers/src/point/{ => models}/normal.ts (58%)
 create mode 100644 packages/layers/src/point/models/text.ts
 create mode 100644 packages/layers/src/polygon/models/extrude.ts
 create mode 100644 packages/layers/src/polygon/models/fill.ts
 create mode 100644 packages/layers/src/polygon/models/index.ts

diff --git a/examples/gallery/basic/demo/arcCircle.js b/examples/gallery/basic/demo/arcCircle.js
index 597aeae5e0..06ffc318b8 100644
--- a/examples/gallery/basic/demo/arcCircle.js
+++ b/examples/gallery/basic/demo/arcCircle.js
@@ -1,4 +1,4 @@
-import { Arc2DLineLayer } from '@l7/layers';
+import { LineLayer } from '@l7/layers';
 import { Scene } from '@l7/scene';
 const scene = new Scene({
   id: 'map',
@@ -13,7 +13,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/UEXQMifxtkQlYfChpPwT.txt')
   .then((res) => res.text())
   .then((data) => {
     const layer =
-    new Arc2DLineLayer({})
+    new LineLayer({})
     .source(data, {
       parser: {
         type: 'csv',
diff --git a/examples/gallery/basic/demo/column_dark.js b/examples/gallery/basic/demo/column_dark.js
index 3633414bf5..13ae28f991 100644
--- a/examples/gallery/basic/demo/column_dark.js
+++ b/examples/gallery/basic/demo/column_dark.js
@@ -1,5 +1,5 @@
 import { Scene } from '@l7/scene';
-import { Point3dLayer} from '@l7/layers'
+import { PointLayer} from '@l7/layers'
 
 const scene = new Scene({
   id: 'map',
@@ -15,7 +15,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json')
   .then((res) => res.json())
   .then((data) => {
     const pointLayer =
-      new Point3dLayer({
+      new PointLayer({
       })
         .source(data.list, {
           parser: {
diff --git a/examples/gallery/basic/demo/normal.js b/examples/gallery/basic/demo/normal.js
index 2ff1f932ab..6c52952426 100644
--- a/examples/gallery/basic/demo/normal.js
+++ b/examples/gallery/basic/demo/normal.js
@@ -1,6 +1,6 @@
 
 import { Scene } from '@l7/scene';
-import { PointNormalLayer } from '@l7/layers'
+import { PointLayer } from '@l7/layers'
 const scene = new Scene({
   id: 'map',
   type: 'amap',
@@ -15,7 +15,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/BElVQFEFvpAKzddxFZxJ.txt')
   .then((res) => res.text())
   .then((data) => {
     const pointLayer =
-      new PointNormalLayer({
+      new PointLayer({
       })
       .source(data, {
         parser: {
diff --git a/examples/gallery/basic/demo/point.js b/examples/gallery/basic/demo/point.js
index 019931bf2b..a5269a917c 100644
--- a/examples/gallery/basic/demo/point.js
+++ b/examples/gallery/basic/demo/point.js
@@ -1,6 +1,6 @@
 
 import { Scene } from '@l7/scene';
-import { PointNormalLayer } from '@l7/layers'
+import { PointLayer } from '@l7/layers'
 const scene = new Scene({
   id: 'map',
   pitch: 64.88,
@@ -15,7 +15,7 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/513add53-dcb2-4295-8860-9e7
   .then((res) => res.json())
   .then((data) => {
     const pointLayer =
-      new PointNormalLayer({
+      new PointLayer({
        
       })
         .source(data)
diff --git a/examples/line/arc/demo/arc.js b/examples/line/arc/demo/arc.js
index 7b398c7da1..6b33943cce 100644
--- a/examples/line/arc/demo/arc.js
+++ b/examples/line/arc/demo/arc.js
@@ -1,4 +1,4 @@
-import { ArcLineLayer } from '@l7/layers';
+import { LineLayer } from '@l7/layers';
 import { Scene } from '@l7/scene';
 const scene = new Scene({
   id: 'map',
@@ -8,11 +8,11 @@ const scene = new Scene({
   center: [0., 23.107329],
   zoom: 0,
 });
-
+console.time('loadData');
 fetch('https://gw.alipayobjects.com/os/basement_prod/b83699f9-a96d-49b8-b2ea-f99299faebaf.json')
   .then((res) => res.json())
   .then((data) => {
-
+    console.timeEnd('loadData');
     function getAirportCoord(idx) {
       return [data.airports[idx][3], data.airports[idx][4]];
     }
@@ -24,9 +24,9 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/b83699f9-a96d-49b8-b2ea-f99
         ]
       }
     });
-
+    console.timeEnd('loadData');
     const layer =
-      new ArcLineLayer({})
+      new LineLayer({})
         .source(routes, {
           parser: {
             type: 'json',
diff --git a/examples/line/arc/demo/arcCircle.js b/examples/line/arc/demo/arcCircle.js
index 597aeae5e0..4e68836834 100644
--- a/examples/line/arc/demo/arcCircle.js
+++ b/examples/line/arc/demo/arcCircle.js
@@ -1,4 +1,4 @@
-import { Arc2DLineLayer } from '@l7/layers';
+import { LineLayer } from '@l7/layers';
 import { Scene } from '@l7/scene';
 const scene = new Scene({
   id: 'map',
@@ -8,28 +8,27 @@ const scene = new Scene({
   center: [107.77791556935472, 35.443286920228644],
   zoom: 2.9142882493605033,
 });
-window.mapScene = scene;
 fetch('https://gw.alipayobjects.com/os/rmsportal/UEXQMifxtkQlYfChpPwT.txt')
   .then((res) => res.text())
   .then((data) => {
     const layer =
-    new Arc2DLineLayer({})
-    .source(data, {
-      parser: {
-        type: 'csv',
-        x: 'lng1',
-        y: 'lat1',
-        x1: 'lng2',
-        y1: 'lat2',
-      },
-    })
-    .size(1)
-    .shape('arc')
-    .color('#8C1EB2')
-    .style({
-      opacity: 0.8,
-      blur: 0.99
-    })
-    ;
-   scene.addLayer(layer);
+      new LineLayer({})
+        .source(data, {
+          parser: {
+            type: 'csv',
+            x: 'lng1',
+            y: 'lat1',
+            x1: 'lng2',
+            y1: 'lat2',
+          },
+        })
+        .size(1)
+        .shape('greatcircle')
+        .color('#8C1EB2')
+        .style({
+          opacity: 0.8,
+          blur: 0.99
+        })
+      ;
+    scene.addLayer(layer);
   })
diff --git a/examples/line/arc/demo/trip_arc.js b/examples/line/arc/demo/trip_arc.js
index 0b838e8304..7f2cee60cf 100644
--- a/examples/line/arc/demo/trip_arc.js
+++ b/examples/line/arc/demo/trip_arc.js
@@ -1,4 +1,4 @@
-import { Arc3DLineLayer } from '@l7/layers';
+import { LineLayer } from '@l7/layers';
 import { Scene } from '@l7/scene';
 const scene = new Scene({
   id: 'map',
@@ -8,12 +8,11 @@ const scene = new Scene({
   center: [-74.06355155037261,40.73507179789368],
   zoom: 11.8623,
 });
-window.mapScene = scene;
 fetch('https://gw.alipayobjects.com/os/basement_prod/bd33a685-a17e-4686-bc79-b0e6a89fd950.csv')
   .then((res) => res.text())
   .then((data) => {
     const layer =
-    new Arc3DLineLayer({})
+    new LineLayer({})
     .source(data, {
       parser: {
         type: 'csv',
@@ -24,7 +23,7 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/bd33a685-a17e-4686-bc79-b0e
       },
     })
     .size(1)
-    .shape('arc')
+    .shape('arc3d')
     .color('#0C47BF')
     .style({
       opacity: 1,
diff --git a/examples/line/arc/demo/trip_arc_dark.js b/examples/line/arc/demo/trip_arc_dark.js
index fc11f18c29..f09d7bf956 100644
--- a/examples/line/arc/demo/trip_arc_dark.js
+++ b/examples/line/arc/demo/trip_arc_dark.js
@@ -1,4 +1,4 @@
-import { Arc3DLineLayer } from '@l7/layers';
+import { LineLayer } from '@l7/layers';
 import { Scene } from '@l7/scene';
 const scene = new Scene({
   id: 'map',
@@ -15,7 +15,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/UEXQMifxtkQlYfChpPwT.txt')
   .then((res) => res.text())
   .then((data) => {
     const layer =
-    new Arc3DLineLayer({})
+    new LineLayer({})
     .source(data, {
       parser: {
         type: 'csv',
@@ -26,7 +26,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/UEXQMifxtkQlYfChpPwT.txt')
       },
     })
     .size(1)
-    .shape('arc')
+    .shape('arc3d')
     .color('#FF7C6A')
     .style({
       opacity: 0.8,
diff --git a/examples/point/bubble/demo/color.js b/examples/point/bubble/demo/color.js
index 09dddb35d8..81cf0df2ba 100644
--- a/examples/point/bubble/demo/color.js
+++ b/examples/point/bubble/demo/color.js
@@ -1,5 +1,5 @@
 import { Scene } from '@l7/scene';
-import { PointLayer, PointImageLayer } from '@l7/layers'
+import { PointLayer } from '@l7/layers'
 const scene = new Scene({
   id: 'map',
   pitch: 0,
diff --git a/examples/point/bubble/demo/meta.json b/examples/point/bubble/demo/meta.json
index ac14fcf566..9c9bf0e4ca 100644
--- a/examples/point/bubble/demo/meta.json
+++ b/examples/point/bubble/demo/meta.json
@@ -8,8 +8,8 @@
       "filename": "point.js",
       "title": "气泡图",
       "screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*_9ETS5_1yCEAAAAAAAAAAABkARQnAQ"
-   
-    }, 
+
+    },
     {
       "filename": "color.js",
       "title": "形状映射",
@@ -19,13 +19,13 @@
       "filename": "world.js",
       "title": "气泡图",
       "screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*DMREQYwsCF4AAAAAAAAAAABkARQnAQ"
-    
-    },
-    {
-      "filename": "normal.js",
-      "title": "城市亮度图",
-      "screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*Xp7iRaORYuIAAAAAAAAAAABkARQnAQ"
-    
+
+    }, {
+      "filename": "scatter.js",
+      "title": "定点图",
+      "screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*Jt3ZSb8VH98AAAAAAAAAAABkARQnAQ"
+
     }
+  
   ]
 }
diff --git a/examples/point/bubble/demo/point.js b/examples/point/bubble/demo/point.js
index 3866c4b935..cf8b433ced 100644
--- a/examples/point/bubble/demo/point.js
+++ b/examples/point/bubble/demo/point.js
@@ -1,5 +1,5 @@
 import { Scene } from '@l7/scene';
-import { PointLayer, PointImageLayer } from '@l7/layers'
+import { PointLayer } from '@l7/layers'
 const scene = new Scene({
   id: 'map',
   pitch: 0,
diff --git a/examples/point/scatter/demo/scatter.js b/examples/point/bubble/demo/scatter.js
similarity index 100%
rename from examples/point/scatter/demo/scatter.js
rename to examples/point/bubble/demo/scatter.js
diff --git a/examples/point/bubble/demo/world.js b/examples/point/bubble/demo/world.js
index 78c8e426c8..7071939514 100644
--- a/examples/point/bubble/demo/world.js
+++ b/examples/point/bubble/demo/world.js
@@ -1,5 +1,5 @@
 import { Scene } from '@l7/scene';
-import { PointLayer, PointImageLayer } from '@l7/layers'
+import { PointLayer } from '@l7/layers'
 const scene = new Scene({
   id: 'map',
   pitch: 0,
@@ -9,7 +9,6 @@ const scene = new Scene({
   zoom: 2.194613775109773,
   maxZoom: 10
 });
-window.mapScene = scene;
 fetch('https://gw.alipayobjects.com/os/basement_prod/337ddbb7-aa3f-4679-ab60-d64359241955.json')
   .then((res) => res.json())
   .then((data) => {
diff --git a/examples/point/column/demo/clumn_shape.js b/examples/point/column/demo/clumn_shape.js
index 5a3e9c1c76..b0e15f99a8 100644
--- a/examples/point/column/demo/clumn_shape.js
+++ b/examples/point/column/demo/clumn_shape.js
@@ -1,11 +1,11 @@
 import { Scene } from '@l7/scene';
-import { Point3dLayer } from '@l7/layers'
+import { PointLayer } from '@l7/layers'
 const scene = new Scene({
   id: 'map',
   pitch: 65.68421052631578,
   type: 'amap',
   style: 'dark',
-  center: [121.3917,31.259242],
+  center: [121.3917, 31.259242],
   zoom: 14.55,
   rotation: 120
 
@@ -16,7 +16,7 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9
   .then((res) => res.json())
   .then((data) => {
     const pointLayer =
-      new Point3dLayer({
+      new PointLayer({
       })
         .source(data, {
           parser: {
@@ -24,16 +24,16 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9
             x: 'longitude',
             y: 'latitude'
           }
-        }).shape('name',['cylinder', 'triangleColumn', 'hexagonColumn','squareColumn'])
-        .size('unit_price', (h)=>{
-          return [ 6,6, h / 500 ]
+        }).shape('name', ['cylinder', 'triangleColumn', 'hexagonColumn', 'squareColumn'])
+        .size('unit_price', (h) => {
+          return [6, 6, h / 500]
         })
-        .color('name',['#739DFF', "#61FCBF",'#FFDE74','#FF896F'])
+        .color('name', ['#739DFF', "#61FCBF", '#FFDE74', '#FF896F'])
         .style({
           opacity: 1.0,
         })
 
-      scene.addLayer(pointLayer);
+    scene.addLayer(pointLayer);
 
   });
 
diff --git a/examples/point/column/demo/clumn_shape_light.js b/examples/point/column/demo/clumn_shape_light.js
index 1b04e5549e..fc56b053db 100644
--- a/examples/point/column/demo/clumn_shape_light.js
+++ b/examples/point/column/demo/clumn_shape_light.js
@@ -1,12 +1,12 @@
 import { Scene } from '@l7/scene';
-import { Point3dLayer } from '@l7/layers'
+import { PointLayer } from '@l7/layers'
 const scene = new Scene({
   id: 'map',
   pitch: 65.68421052631578,
   type: 'mapbox',
   style: 'light',
-  center: [121.3917,31.259242],
-  zoom: 14.55,
+  center: [121.3917, 31.259242],
+  zoom: 13.55,
   rotation: 120
 
 });
@@ -16,7 +16,7 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9
   .then((res) => res.json())
   .then((data) => {
     const pointLayer =
-      new Point3dLayer({
+      new PointLayer({
       })
         .source(data, {
           parser: {
@@ -24,16 +24,16 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9
             x: 'longitude',
             y: 'latitude'
           }
-        }).shape('name',['cylinder', 'triangleColumn', 'hexagonColumn','squareColumn'])
-        .size('unit_price', (h)=>{
-          return [ 6,6, h / 500 ]
+        }).shape('name', ['cylinder', 'triangleColumn', 'hexagonColumn', 'squareColumn'])
+        .size('unit_price', (h) => {
+          return [6, 6, h / 500]
         })
-        .color('name',['#5B8FF9', "#70E3B5",'#FFD458','#FF7C6A'])
+        .color('name', ['#5B8FF9', "#70E3B5", '#FFD458', '#FF7C6A'])
         .style({
           opacity: 1.0,
         })
 
-      scene.addLayer(pointLayer);
+    scene.addLayer(pointLayer);
 
   });
 
diff --git a/examples/point/column/demo/column_dark.js b/examples/point/column/demo/column_dark.js
index 3633414bf5..510a465964 100644
--- a/examples/point/column/demo/column_dark.js
+++ b/examples/point/column/demo/column_dark.js
@@ -1,5 +1,5 @@
 import { Scene } from '@l7/scene';
-import { Point3dLayer} from '@l7/layers'
+import { PointLayer } from '@l7/layers'
 
 const scene = new Scene({
   id: 'map',
@@ -15,7 +15,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json')
   .then((res) => res.json())
   .then((data) => {
     const pointLayer =
-      new Point3dLayer({
+      new PointLayer({
       })
         .source(data.list, {
           parser: {
@@ -23,22 +23,22 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json')
             x: 'j',
             y: 'w'
           }
-        }) 
+        })
         .shape('cylinder')
-        .size('t', function(level) {
+        .size('t', function (level) {
           return [1, 2, level * 2 + 20];
         })
-        .color('t',[
+        .color('t', [
           '#094D4A', '#146968',
           '#1D7F7E', '#289899',
           '#34B6B7', '#4AC5AF',
           '#5FD3A6', '#7BE39E',
           '#A1EDB8', '#CEF8D6'
-        ],)
+        ])
         .style({
           opacity: 1.0,
         })
-        scene.addLayer(pointLayer);
-        console.log(pointLayer);
-       
+    scene.addLayer(pointLayer);
+    console.log(pointLayer);
+
   });
\ No newline at end of file
diff --git a/examples/point/column/demo/column_light.js b/examples/point/column/demo/column_light.js
index 533383f793..adcc29fa43 100644
--- a/examples/point/column/demo/column_light.js
+++ b/examples/point/column/demo/column_light.js
@@ -1,5 +1,5 @@
 import { Scene } from '@l7/scene';
-import { Point3dLayer} from '@l7/layers'
+import { PointLayer } from '@l7/layers'
 
 const scene = new Scene({
   id: 'map',
@@ -15,7 +15,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json')
   .then((res) => res.json())
   .then((data) => {
     const pointLayer =
-      new Point3dLayer({
+      new PointLayer({
       })
         .source(data.list, {
           parser: {
@@ -23,16 +23,16 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json')
             x: 'j',
             y: 'w'
           }
-        }) 
+        })
         .shape('cylinder')
-        .size('t', function(level) {
+        .size('t', function (level) {
           return [1, 2, level * 2 + 20];
         })
         .color('#006CFF')
         .style({
           opacity: 1.0,
         })
-        scene.addLayer(pointLayer);
-        console.log(pointLayer);
-       
+    scene.addLayer(pointLayer);
+    console.log(pointLayer);
+
   });
\ No newline at end of file
diff --git a/examples/point/image/demo/image.js b/examples/point/image/demo/image.js
index 7a27ead997..5da7f57cb4 100644
--- a/examples/point/image/demo/image.js
+++ b/examples/point/image/demo/image.js
@@ -1,31 +1,31 @@
 import { Scene } from '@l7/scene';
-import { PointImageLayer } from '@l7/layers'
+import { PointLayer } from '@l7/layers'
 console.log(this);
 const scene = new Scene({
   id: 'map',
   pitch: 0,
   type: 'amap',
   style: 'light',
-  center: [121.434765,31.256735],
+  center: [121.434765, 31.256735],
   zoom: 14.83,
 });
 
 fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9140d288ae.json')
   .then((res) => res.json())
   .then((data) => {
-  scene.addImage(
-    '00',
-    'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg',
-  );
-  scene.addImage(
-    '01',
-    'https://gw.alipayobjects.com/zos/basement_prod/30580bc9-506f-4438-8c1a-744e082054ec.svg',
-  );
-  scene.addImage(
-    '02',
-    'https://gw.alipayobjects.com/zos/basement_prod/7aa1f460-9f9f-499f-afdf-13424aa26bbf.svg',
-  );
-   const imageLayer = new PointImageLayer()
+    scene.addImage(
+      '00',
+      'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg',
+    );
+    scene.addImage(
+      '01',
+      'https://gw.alipayobjects.com/zos/basement_prod/30580bc9-506f-4438-8c1a-744e082054ec.svg',
+    );
+    scene.addImage(
+      '02',
+      'https://gw.alipayobjects.com/zos/basement_prod/7aa1f460-9f9f-499f-afdf-13424aa26bbf.svg',
+    );
+    const imageLayer = new PointLayer()
       .source(data, {
         parser: {
           type: 'json',
@@ -33,9 +33,9 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/893d1d5f-11d9-45f3-8322-ee9
           y: 'latitude'
         }
       })
-      .shape('name', ['00', '01','02'])
+      .shape('name', ['00', '01', '02'])
       .size(20);
-        scene.addLayer(imageLayer);
+    scene.addLayer(imageLayer);
   });
 
 
diff --git a/examples/point/image/demo/locate.js b/examples/point/image/demo/locate.js
index 1ae31084bb..c067cabf80 100644
--- a/examples/point/image/demo/locate.js
+++ b/examples/point/image/demo/locate.js
@@ -1,6 +1,5 @@
 import { Scene } from '@l7/scene';
-import { PointImageLayer } from '@l7/layers'
-console.log(this);
+import { PointLayer } from '@l7/layers'
 const scene = new Scene({
   id: 'map',
   pitch: 0,
@@ -13,18 +12,17 @@ const scene = new Scene({
 fetch('https://gw.alipayobjects.com/os/basement_prod/e2fc6e0a-af2a-4320-96e5-d9f5a5fda442.json')
   .then((res) => res.json())
   .then((data) => {
-  scene.addImage(
-    'marker',
-    'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*BJ6cTpDcuLcAAAAAAAAAAABkARQnAQ',
-  );
-   const imageLayer = new PointImageLayer()
-      .source(data,)
+    scene.addImage(
+      'marker',
+      'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*BJ6cTpDcuLcAAAAAAAAAAABkARQnAQ',
+    );
+    const imageLayer = new PointLayer()
+      .source(data)
       .shape('marker')
       .size(12);
-        scene.addLayer(imageLayer);
+    scene.addLayer(imageLayer);
 
   });
 
-window.mapscene =scene;
 
 
diff --git a/examples/point/image/demo/weather.js b/examples/point/image/demo/weather.js
index 9df619e98d..d7634d3d56 100644
--- a/examples/point/image/demo/weather.js
+++ b/examples/point/image/demo/weather.js
@@ -1,5 +1,5 @@
 import { Scene } from '@l7/scene';
-import { PointImageLayer } from '@l7/layers'
+import { PointLayer } from '@l7/layers'
 const scene = new Scene({
   id: 'map',
   type: 'amap',
@@ -25,13 +25,13 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/c6042c6b-45fd-4e2e-adf8-fdb
   .then((res) => res.json())
   .then((data) => {
 
-   const imageLayer = new PointImageLayer()
+    const imageLayer = new PointLayer()
       .source(data)
-      .shape('w', function(w) {
+      .shape('w', function (w) {
         return w;
       })
       .size(15)
-       scene.addLayer(imageLayer);
+    scene.addLayer(imageLayer);
   });
 
 
diff --git a/examples/point/scatter/demo/meta.json b/examples/point/scatter/demo/meta.json
index 2072bea186..f592a11c51 100644
--- a/examples/point/scatter/demo/meta.json
+++ b/examples/point/scatter/demo/meta.json
@@ -5,10 +5,9 @@
   },
   "demos": [
     {
-      "filename": "scatter.js",
-      "title": "定点图",
-      "screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*Jt3ZSb8VH98AAAAAAAAAAABkARQnAQ"
-
+      "filename": "normal2.js",
+      "title": "城市亮度图",
+      "screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*Xp7iRaORYuIAAAAAAAAAAABkARQnAQ"
     },
     {
       "filename": "normal.js",
diff --git a/examples/point/scatter/demo/normal.js b/examples/point/scatter/demo/normal.js
index 2ff1f932ab..6c52952426 100644
--- a/examples/point/scatter/demo/normal.js
+++ b/examples/point/scatter/demo/normal.js
@@ -1,6 +1,6 @@
 
 import { Scene } from '@l7/scene';
-import { PointNormalLayer } from '@l7/layers'
+import { PointLayer } from '@l7/layers'
 const scene = new Scene({
   id: 'map',
   type: 'amap',
@@ -15,7 +15,7 @@ fetch('https://gw.alipayobjects.com/os/rmsportal/BElVQFEFvpAKzddxFZxJ.txt')
   .then((res) => res.text())
   .then((data) => {
     const pointLayer =
-      new PointNormalLayer({
+      new PointLayer({
       })
       .source(data, {
         parser: {
diff --git a/examples/point/bubble/demo/normal.js b/examples/point/scatter/demo/normal2.js
similarity index 90%
rename from examples/point/bubble/demo/normal.js
rename to examples/point/scatter/demo/normal2.js
index 019931bf2b..a5269a917c 100644
--- a/examples/point/bubble/demo/normal.js
+++ b/examples/point/scatter/demo/normal2.js
@@ -1,6 +1,6 @@
 
 import { Scene } from '@l7/scene';
-import { PointNormalLayer } from '@l7/layers'
+import { PointLayer } from '@l7/layers'
 const scene = new Scene({
   id: 'map',
   pitch: 64.88,
@@ -15,7 +15,7 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/513add53-dcb2-4295-8860-9e7
   .then((res) => res.json())
   .then((data) => {
     const pointLayer =
-      new PointNormalLayer({
+      new PointLayer({
        
       })
         .source(data)
diff --git a/examples/polygon/3d/demo/polygon.js b/examples/polygon/3d/demo/polygon.js
index 2774579d1c..90521c91ef 100644
--- a/examples/polygon/3d/demo/polygon.js
+++ b/examples/polygon/3d/demo/polygon.js
@@ -1,5 +1,5 @@
 import { Scene } from '@l7/scene';
-import { Polygon3DLayer  } from '@l7/layers'
+import { PolygonLayer  } from '@l7/layers'
 const scene = new Scene({
   id: 'map',
   pitch: 15.05263,
@@ -14,10 +14,10 @@ fetch('https://gw.alipayobjects.com/os/basement_prod/972566c5-a2b9-4a7e-8da1-bae
   .then((res) => res.json())
   .then((data) => {
     const layer =
-      new Polygon3DLayer ({
+      new PolygonLayer ({
       })
       .source(data)
-      .shape('fill')
+      .shape('extrude')
       .size('h20',[100, 120, 160, 200, 260, 500])
       .color('h20', ['#816CAD',
       '#A67FB5', '#C997C7',
diff --git a/packages/core/src/services/layer/ILayerService.ts b/packages/core/src/services/layer/ILayerService.ts
index d84e9b0c8b..f1361fbf20 100644
--- a/packages/core/src/services/layer/ILayerService.ts
+++ b/packages/core/src/services/layer/ILayerService.ts
@@ -1,8 +1,9 @@
 import { SyncBailHook, SyncHook } from 'tapable';
 import Clock from '../../utils/clock';
 import { IGlobalConfigService } from '../config/IConfigService';
-import { IModel } from '../renderer/IModel';
+import { IModel, IModelInitializationOptions } from '../renderer/IModel';
 import { IMultiPassRenderer } from '../renderer/IMultiPassRenderer';
+import { IUniform } from '../renderer/IUniform';
 import { ISource, ISourceCFG } from '../source/ISourceService';
 import {
   IAnimateOption,
@@ -12,6 +13,7 @@ import {
   IStyleAttributeService,
   StyleAttrField,
   StyleAttributeOption,
+  Triangulation,
 } from './IStyleAttributeService';
 
 export interface ILayerGlobalConfig {
@@ -24,6 +26,19 @@ export interface ILayerGlobalConfig {
     [key: string]: IScale;
   };
 }
+export interface ILayerModelInitializationOptions {
+  moduleName: string;
+  vertexShader: string;
+  fragmentShader: string;
+  triangulation: Triangulation;
+}
+export interface ILayerModel {
+  getUninforms(): IModelUniform;
+  buildModels(): IModel[];
+}
+export interface IModelUniform {
+  [key: string]: IUniform;
+}
 
 export interface IPickedFeature {
   x: number;
@@ -59,6 +74,10 @@ export interface ILayer {
   };
   multiPassRenderer: IMultiPassRenderer;
   styleAttributeService: IStyleAttributeService;
+  buildLayerModel(
+    options: ILayerModelInitializationOptions &
+      Partial<IModelInitializationOptions>,
+  ): IModel;
   init(): ILayer;
   size(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
   color(field: StyleAttrField, value?: StyleAttributeOption): ILayer;
diff --git a/packages/layers/src/core/BaseLayer.ts b/packages/layers/src/core/BaseLayer.ts
index fcb90df68b..d429712f89 100644
--- a/packages/layers/src/core/BaseLayer.ts
+++ b/packages/layers/src/core/BaseLayer.ts
@@ -9,6 +9,8 @@ import {
   IInteractionService,
   ILayer,
   ILayerInitializationOptions,
+  ILayerModel,
+  ILayerModelInitializationOptions,
   ILayerPlugin,
   ILayerService,
   IMapService,
@@ -38,13 +40,6 @@ import { SyncBailHook, SyncHook } from 'tapable';
 import { normalizePasses } from '../plugins/MultiPassRendererPlugin';
 import baseLayerSchema from './schema';
 
-export interface ILayerModelInitializationOptions {
-  moduleName: string;
-  vertexShader: string;
-  fragmentShader: string;
-  triangulation: Triangulation;
-}
-
 /**
  * 分配 layer id
  */
@@ -110,15 +105,15 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> extends EventEmitter
   public readonly configService: IGlobalConfigService;
 
   @lazyInject(TYPES.IIconService)
-  protected readonly iconService: IIconService;
+  public readonly iconService: IIconService;
 
   @lazyInject(TYPES.IFontService)
-  protected readonly fontService: IFontService;
-
-  protected layerSource: Source;
+  public readonly fontService: IFontService;
 
   @lazyInject(TYPES.IRendererService)
-  protected readonly rendererService: IRendererService;
+  public readonly rendererService: IRendererService;
+
+  protected layerSource: Source;
 
   @lazyInject(TYPES.IShaderModuleService)
   protected readonly shaderModuleService: IShaderModuleService;
@@ -129,6 +124,8 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> extends EventEmitter
   @lazyInject(TYPES.ILayerService)
   protected readonly layerService: ILayerService;
 
+  protected layerModel: ILayerModel;
+
   protected enodeOptions: {
     [type: string]: {
       field: StyleAttributeField;
@@ -441,7 +438,7 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> extends EventEmitter
     this.interactionService.triggerHover({ x, y });
   }
 
-  protected buildLayerModel(
+  public buildLayerModel(
     options: ILayerModelInitializationOptions &
       Partial<IModelInitializationOptions>,
   ): IModel {
diff --git a/packages/layers/src/core/baseModel.ts b/packages/layers/src/core/baseModel.ts
new file mode 100644
index 0000000000..78201d7479
--- /dev/null
+++ b/packages/layers/src/core/baseModel.ts
@@ -0,0 +1,55 @@
+import {
+  AttributeType,
+  gl,
+  IEncodeFeature,
+  IFontService,
+  IGlobalConfigService,
+  IIconService,
+  ILayer,
+  ILayerModel,
+  ILayerPlugin,
+  ILogService,
+  IMapService,
+  IModel,
+  IModelUniform,
+  IRendererService,
+  IStyleAttributeService,
+  lazyInject,
+  TYPES,
+} from '@l7/core';
+
+export default class BaseModel implements ILayerModel {
+  protected layer: ILayer;
+
+  @lazyInject(TYPES.IGlobalConfigService)
+  protected readonly configService: IGlobalConfigService;
+
+  @lazyInject(TYPES.IIconService)
+  protected readonly iconService: IIconService;
+
+  @lazyInject(TYPES.IFontService)
+  protected readonly fontService: IFontService;
+
+  @lazyInject(TYPES.IRendererService)
+  protected readonly rendererService: IRendererService;
+
+  @lazyInject(TYPES.IMapService)
+  protected readonly map: IMapService;
+
+  constructor(layer: ILayer) {
+    this.layer = layer;
+    this.registerBuiltinAttributes();
+  }
+
+  public getUninforms(): IModelUniform {
+    throw new Error('Method not implemented.');
+  }
+
+  public buildModels(): IModel[] {
+    throw new Error('Method not implemented.');
+  }
+
+  protected registerBuiltinAttributes() {
+    throw new Error('Method not implemented.');
+  }
+}
diff --git a/packages/layers/src/core/triangulation.ts b/packages/layers/src/core/triangulation.ts
index 97495b5bb9..896309f71f 100644
--- a/packages/layers/src/core/triangulation.ts
+++ b/packages/layers/src/core/triangulation.ts
@@ -1,5 +1,6 @@
 import { IEncodeFeature } from '@l7/core';
 import { aProjectFlat, lngLatToMeters } from '@l7/utils';
+import earcut from 'earcut';
 import { vec3 } from 'gl-matrix';
 import getNormals from '../utils/polylineNormal';
 import extrudePolygon, {
@@ -82,6 +83,18 @@ export function LineTriangulation(feature: IEncodeFeature) {
   };
 }
 
+export function polygonTriangulation(feature: IEncodeFeature) {
+  const { coordinates } = feature;
+  const flattengeo = earcut.flatten(coordinates as number[][][]);
+  const { vertices, dimensions, holes } = flattengeo;
+
+  return {
+    indices: earcut(vertices, holes, dimensions),
+    vertices,
+    size: dimensions,
+  };
+}
+
 export function PolygonExtrudeTriangulation(feature: IEncodeFeature) {
   const coordinates = feature.coordinates as IPosition[][];
   const { positions, index, normals } = extrude_PolygonNormal(
@@ -155,7 +168,7 @@ export function RasterImageTriangulation(feature: IEncodeFeature) {
  * @param segNum 弧线线段数
  */
 export function LineArcTriangulation(feature: IEncodeFeature) {
-  const segNum = 30;
+  const segNum = 20;
   const coordinates = feature.coordinates as IPosition[];
   const positions = [];
   const indexArray = [];
diff --git a/packages/layers/src/index.ts b/packages/layers/src/index.ts
index e52676d63d..f638f93223 100644
--- a/packages/layers/src/index.ts
+++ b/packages/layers/src/index.ts
@@ -4,20 +4,15 @@ import HeatMapGrid3dLayer from './heatmap/gird3d';
 import HeatMapGridLayer from './heatmap/grid';
 import HeatMapLayer from './heatmap/heatmap';
 import HeatMapHexagonLayer from './heatmap/hexagon';
-import ArcLineLayer from './line/arc';
-import Arc2DLineLayer from './line/arc2d';
-import Arc3DLineLayer from './line/arc3d';
+
 import DashLineLayer from './line/dash';
 import LineLayer from './line/index';
-import Point3dLayer from './point/extrude';
-import PointLayer from './point/fill';
-import PointImageLayer from './point/image';
-import PointNormalLayer from './point/normal';
+import PointLayer from './point';
 
 import TextLayer from './point/text';
 // import Point from './point/point';
 import PolygonLayer from './polygon';
-import Polygon3DLayer from './polygon/polygon3D';
+// import Polygon3DLayer from './polygon/polygon3D';
 import ImageLayer from './raster/image';
 import RasterLayer from './raster/raster';
 import Raster2DLayer from './raster/raster2d';
@@ -83,19 +78,13 @@ export {
   BaseLayer,
   PointLayer,
   PolygonLayer,
-  Point3dLayer,
-  PointImageLayer,
   LineLayer,
   DashLineLayer,
-  Polygon3DLayer,
+  // Polygon3DLayer,
   ImageLayer,
-  ArcLineLayer,
-  Arc2DLineLayer,
-  Arc3DLineLayer,
   RasterLayer,
   HeatMapLayer,
   TextLayer,
-  PointNormalLayer,
   HeatMapGrid3dLayer,
   HeatMapHexagonLayer,
   HeatMapGridLayer,
diff --git a/packages/layers/src/line/index.ts b/packages/layers/src/line/index.ts
index 66a8e3f3bf..a7f431164a 100644
--- a/packages/layers/src/line/index.ts
+++ b/packages/layers/src/line/index.ts
@@ -1,8 +1,6 @@
 import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core';
 import BaseLayer from '../core/BaseLayer';
-import { LineTriangulation } from '../core/triangulation';
-import line_frag from './shaders/line_frag.glsl';
-import line_vert from './shaders/line_vert.glsl';
+import LineModels, { LineModelType } from './models';
 interface IPointLayerStyleOptions {
   opacity: number;
 }
@@ -24,129 +22,24 @@ export default class LineLayer extends BaseLayer<IPointLayerStyleOptions> {
   }
 
   protected renderModels() {
-    const {
-      enable,
-      interval = 0.2,
-      trailLength = 0.2,
-      duration = 2,
-    } = this.animateOptions;
-    const animate = enable ? 1 : 0;
-    const { opacity } = this.getStyleOptions();
     this.models.forEach((model) =>
       model.draw({
-        uniforms: {
-          u_opacity: opacity || 1.0,
-          u_time:
-            this.layerService.clock.getElapsedTime() - this.animateStartTime,
-          u_animate: [animate, duration, interval, trailLength],
-        },
+        uniforms: this.layerModel.getUninforms(),
       }),
     );
     return this;
   }
 
   protected buildModels() {
-    this.registerBuiltinAttributes(this);
-    this.models = [
-      this.buildLayerModel({
-        moduleName: 'line',
-        vertexShader: line_vert,
-        fragmentShader: line_frag,
-        triangulation: LineTriangulation,
-        blend: {
-          enable: true,
-          func: {
-            srcRGB: gl.SRC_ALPHA,
-            srcAlpha: 1,
-            dstRGB: gl.ONE_MINUS_SRC_ALPHA,
-            dstAlpha: 1,
-          },
-        },
-      }),
-    ];
-    // this.initAnimate();
+    const shape = this.getModelType();
+    this.layerModel = new LineModels[shape](this);
+    this.models = this.layerModel.buildModels();
   }
-
-  private registerBuiltinAttributes(layer: ILayer) {
-    // point layer size;
-    layer.styleAttributeService.registerStyleAttribute({
-      name: 'size',
-      type: AttributeType.Attribute,
-      descriptor: {
-        name: 'a_Size',
-        buffer: {
-          // give the WebGL driver a hint that this buffer may change
-          usage: gl.DYNAMIC_DRAW,
-          data: [],
-          type: gl.FLOAT,
-        },
-        size: 2,
-        update: (
-          feature: IEncodeFeature,
-          featureIdx: number,
-          vertex: number[],
-          attributeIdx: number,
-        ) => {
-          const { size } = feature;
-          return Array.isArray(size) ? [size[0], size[1]] : [size as number, 0];
-        },
-      },
-    });
-
-    // point layer size;
-    layer.styleAttributeService.registerStyleAttribute({
-      name: 'normal',
-      type: AttributeType.Attribute,
-      descriptor: {
-        name: 'a_Normal',
-        buffer: {
-          // give the WebGL driver a hint that this buffer may change
-          usage: gl.STATIC_DRAW,
-          data: [],
-          type: gl.FLOAT,
-        },
-        size: 3,
-        update: (
-          feature: IEncodeFeature,
-          featureIdx: number,
-          vertex: number[],
-          attributeIdx: number,
-          normal: number[],
-        ) => {
-          return normal;
-        },
-      },
-    });
-
-    layer.styleAttributeService.registerStyleAttribute({
-      name: 'miter',
-      type: AttributeType.Attribute,
-      descriptor: {
-        name: 'a_Miter',
-        buffer: {
-          // give the WebGL driver a hint that this buffer may change
-          usage: gl.DYNAMIC_DRAW,
-          data: [],
-          type: gl.FLOAT,
-        },
-        size: 1,
-        update: (
-          feature: IEncodeFeature,
-          featureIdx: number,
-          vertex: number[],
-          attributeIdx: number,
-        ) => {
-          return [vertex[4]];
-        },
-      },
-    });
-  }
-  // 拆分的动画插件
-  private initAnimate() {
-    const { enable } = this.animateOptions;
-    if (enable) {
-      this.layerService.startAnimate();
-      this.animateStartTime = this.layerService.clock.getElapsedTime();
-    }
+  private getModelType(): LineModelType {
+    const shapeAttribute = this.styleAttributeService.getLayerStyleAttribute(
+      'shape',
+    );
+    const shape = shapeAttribute?.scale?.field as LineModelType;
+    return shape || 'line';
   }
 }
diff --git a/packages/layers/src/line/arc.ts b/packages/layers/src/line/models/arc.ts
similarity index 58%
rename from packages/layers/src/line/arc.ts
rename to packages/layers/src/line/models/arc.ts
index aa325cfc13..ef8a5816f7 100644
--- a/packages/layers/src/line/arc.ts
+++ b/packages/layers/src/line/models/arc.ts
@@ -1,46 +1,39 @@
-import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core';
-import BaseLayer from '../core/BaseLayer';
-import { LineArcTriangulation } from '../core/triangulation';
-import line_arc_frag from './shaders/line_arc_frag.glsl';
-import line_arc2d_vert from './shaders/line_bezier_vert.glsl';
+import {
+  AttributeType,
+  gl,
+  IEncodeFeature,
+  ILayer,
+  ILayerModel,
+  IModel,
+  IModelUniform,
+} from '@l7/core';
+
+import BaseModel from '../../core/baseModel';
+import { LineArcTriangulation } from '../../core/triangulation';
+import line_arc_frag from '../shaders/line_arc_frag.glsl';
+import line_arc2d_vert from '../shaders/line_bezier_vert.glsl';
+
 interface IArcLayerStyleOptions {
   opacity: number;
   segmentNumber: number;
   blur: number;
 }
-export default class ArcLineLayer extends BaseLayer<IArcLayerStyleOptions> {
-  public name: string = 'LineLayer';
-
-  protected getConfigSchema() {
+export default class ArcModel extends BaseModel {
+  public getUninforms(): IModelUniform {
+    const {
+      opacity,
+      blur = 0.99,
+    } = this.layer.getStyleOptions() as IArcLayerStyleOptions;
     return {
-      properties: {
-        opacity: {
-          type: 'number',
-          minimum: 0,
-          maximum: 1,
-        },
-      },
+      u_opacity: opacity || 1,
+      segmentNumber: 30,
+      u_blur: blur,
     };
   }
 
-  protected renderModels() {
-    const { opacity, blur = 0.99 } = this.getStyleOptions();
-    this.models.forEach((model) =>
-      model.draw({
-        uniforms: {
-          u_opacity: opacity || 1,
-          segmentNumber: 30,
-          u_blur: blur,
-        },
-      }),
-    );
-    return this;
-  }
-
-  protected buildModels() {
-    this.registerBuiltinAttributes(this);
-    this.models = [
-      this.buildLayerModel({
+  public buildModels(): IModel[] {
+    return [
+      this.layer.buildLayerModel({
         moduleName: 'arc2dline',
         vertexShader: line_arc2d_vert,
         fragmentShader: line_arc_frag,
@@ -59,9 +52,9 @@ export default class ArcLineLayer extends BaseLayer<IArcLayerStyleOptions> {
     ];
   }
 
-  private registerBuiltinAttributes(layer: ILayer) {
+  protected registerBuiltinAttributes() {
     // point layer size;
-    layer.styleAttributeService.registerStyleAttribute({
+    this.layer.styleAttributeService.registerStyleAttribute({
       name: 'size',
       type: AttributeType.Attribute,
       descriptor: {
@@ -85,7 +78,7 @@ export default class ArcLineLayer extends BaseLayer<IArcLayerStyleOptions> {
       },
     });
 
-    layer.styleAttributeService.registerStyleAttribute({
+    this.layer.styleAttributeService.registerStyleAttribute({
       name: 'instance', // 弧线起始点信息
       type: AttributeType.Attribute,
       descriptor: {
diff --git a/packages/layers/src/line/arc3d.ts b/packages/layers/src/line/models/arc_3d.ts
similarity index 58%
rename from packages/layers/src/line/arc3d.ts
rename to packages/layers/src/line/models/arc_3d.ts
index 369ca56356..5c3ff2bd72 100644
--- a/packages/layers/src/line/arc3d.ts
+++ b/packages/layers/src/line/models/arc_3d.ts
@@ -1,44 +1,33 @@
-import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core';
-import BaseLayer from '../core/BaseLayer';
-import { LineArcTriangulation } from '../core/triangulation';
-import line_arc_frag from './shaders/line_arc_frag.glsl';
-import line_arc_vert from './shaders/line_arc_vert.glsl';
+import {
+  AttributeType,
+  gl,
+  IEncodeFeature,
+  ILayer,
+  ILayerModel,
+  IModel,
+  IModelUniform,
+} from '@l7/core';
+import BaseModel from '../../core/baseModel';
+import { LineArcTriangulation } from '../../core/triangulation';
+import line_arc_frag from '../shaders/line_arc_frag.glsl';
+import line_arc_vert from '../shaders/line_arc_vert.glsl';
+
 interface IArcLayerStyleOptions {
   opacity: number;
   segmentNumber: number;
 }
-export default class Arc3DLineLayer extends BaseLayer<IArcLayerStyleOptions> {
-  public name: string = 'LineLayer';
-
-  protected getConfigSchema() {
+export default class Arc3DModel extends BaseModel {
+  public getUninforms(): IModelUniform {
+    const { opacity } = this.layer.getStyleOptions() as IArcLayerStyleOptions;
     return {
-      properties: {
-        opacity: {
-          type: 'number',
-          minimum: 0,
-          maximum: 1,
-        },
-      },
+      u_opacity: opacity || 1,
+      segmentNumber: 30,
     };
   }
 
-  protected renderModels() {
-    const { opacity } = this.getStyleOptions();
-    this.models.forEach((model) =>
-      model.draw({
-        uniforms: {
-          u_opacity: opacity || 1,
-          segmentNumber: 30,
-        },
-      }),
-    );
-    return this;
-  }
-
-  protected buildModels() {
-    this.registerBuiltinAttributes(this);
-    this.models = [
-      this.buildLayerModel({
+  public buildModels(): IModel[] {
+    return [
+      this.layer.buildLayerModel({
         moduleName: 'arcline',
         vertexShader: line_arc_vert,
         fragmentShader: line_arc_frag,
@@ -55,10 +44,9 @@ export default class Arc3DLineLayer extends BaseLayer<IArcLayerStyleOptions> {
       }),
     ];
   }
-
-  private registerBuiltinAttributes(layer: ILayer) {
+  protected registerBuiltinAttributes() {
     // point layer size;
-    layer.styleAttributeService.registerStyleAttribute({
+    this.layer.styleAttributeService.registerStyleAttribute({
       name: 'size',
       type: AttributeType.Attribute,
       descriptor: {
@@ -82,7 +70,7 @@ export default class Arc3DLineLayer extends BaseLayer<IArcLayerStyleOptions> {
       },
     });
 
-    layer.styleAttributeService.registerStyleAttribute({
+    this.layer.styleAttributeService.registerStyleAttribute({
       name: 'instance', // 弧线起始点信息
       type: AttributeType.Attribute,
       descriptor: {
diff --git a/packages/layers/src/line/models/dash.ts b/packages/layers/src/line/models/dash.ts
new file mode 100644
index 0000000000..7aa44a4dbc
--- /dev/null
+++ b/packages/layers/src/line/models/dash.ts
@@ -0,0 +1,22 @@
+import {
+  AttributeType,
+  gl,
+  IEncodeFeature,
+  ILayer,
+  ILayerModel,
+  IModel,
+} from '@l7/core';
+
+import BaseModel from '../../core/baseModel';
+export default class ArcModel extends BaseModel {
+  public getUninforms() {
+    throw new Error('Method not implemented.');
+  }
+
+  public buildModels(): IModel[] {
+    throw new Error('Method not implemented.');
+  }
+  private registerBuiltinAttributes() {
+    throw new Error('Method not implemented.');
+  }
+}
diff --git a/packages/layers/src/line/arc2d.ts b/packages/layers/src/line/models/great_circle.ts
similarity index 58%
rename from packages/layers/src/line/arc2d.ts
rename to packages/layers/src/line/models/great_circle.ts
index c35b23edba..5a990694e5 100644
--- a/packages/layers/src/line/arc2d.ts
+++ b/packages/layers/src/line/models/great_circle.ts
@@ -1,48 +1,39 @@
-import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core';
-import BaseLayer from '../core/BaseLayer';
-import { LineArcTriangulation } from '../core/triangulation';
-import line_arc2d_vert from './shaders/line_arc2d_vert.glsl';
-import line_arc_frag from './shaders/line_arc_frag.glsl';
+import {
+  AttributeType,
+  gl,
+  IEncodeFeature,
+  ILayer,
+  ILayerModel,
+  IModel,
+  IModelUniform,
+} from '@l7/core';
+
+import BaseModel from '../../core/baseModel';
+import { LineArcTriangulation } from '../../core/triangulation';
+import line_arc2d_vert from '../shaders/line_arc2d_vert.glsl';
+import line_arc_frag from '../shaders/line_arc_frag.glsl';
+
 interface IArcLayerStyleOptions {
   opacity: number;
   segmentNumber: number;
   blur: number;
 }
-export default class ArcCircleLineLayer extends BaseLayer<
-  IArcLayerStyleOptions
-> {
-  public name: string = 'LineLayer';
-
-  protected getConfigSchema() {
+export default class GreatCircleModel extends BaseModel {
+  public getUninforms(): IModelUniform {
+    const {
+      opacity,
+      blur = 0.99,
+    } = this.layer.getStyleOptions() as IArcLayerStyleOptions;
     return {
-      properties: {
-        opacity: {
-          type: 'number',
-          minimum: 0,
-          maximum: 1,
-        },
-      },
+      u_opacity: opacity || 1,
+      segmentNumber: 30,
+      u_blur: blur,
     };
   }
 
-  protected renderModels() {
-    const { opacity, blur = 0.99 } = this.getStyleOptions();
-    this.models.forEach((model) =>
-      model.draw({
-        uniforms: {
-          u_opacity: opacity || 1,
-          segmentNumber: 30,
-          u_blur: blur,
-        },
-      }),
-    );
-    return this;
-  }
-
-  protected buildModels() {
-    this.registerBuiltinAttributes(this);
-    this.models = [
-      this.buildLayerModel({
+  public buildModels(): IModel[] {
+    return [
+      this.layer.buildLayerModel({
         moduleName: 'arc2dline',
         vertexShader: line_arc2d_vert,
         fragmentShader: line_arc_frag,
@@ -60,10 +51,9 @@ export default class ArcCircleLineLayer extends BaseLayer<
       }),
     ];
   }
-
-  private registerBuiltinAttributes(layer: ILayer) {
+  protected registerBuiltinAttributes() {
     // point layer size;
-    layer.styleAttributeService.registerStyleAttribute({
+    this.layer.styleAttributeService.registerStyleAttribute({
       name: 'size',
       type: AttributeType.Attribute,
       descriptor: {
@@ -87,7 +77,7 @@ export default class ArcCircleLineLayer extends BaseLayer<
       },
     });
 
-    layer.styleAttributeService.registerStyleAttribute({
+    this.layer.styleAttributeService.registerStyleAttribute({
       name: 'instance', // 弧线起始点信息
       type: AttributeType.Attribute,
       descriptor: {
diff --git a/packages/layers/src/line/models/index.ts b/packages/layers/src/line/models/index.ts
new file mode 100644
index 0000000000..54a3a124e8
--- /dev/null
+++ b/packages/layers/src/line/models/index.ts
@@ -0,0 +1,15 @@
+import ArcModel from './arc';
+import Arc3DModel from './arc_3d';
+import GreatCircleModel from './great_circle';
+import LineModel from './line';
+
+export type LineModelType = 'arc' | 'arc3d' | 'greatcircle' | 'line';
+
+const LineModels: { [key in LineModelType]: any } = {
+  arc: ArcModel,
+  arc3d: Arc3DModel,
+  greatcircle: GreatCircleModel,
+  line: LineModel,
+};
+
+export default LineModels;
diff --git a/packages/layers/src/line/models/line.ts b/packages/layers/src/line/models/line.ts
new file mode 100644
index 0000000000..c4c8bcd0c3
--- /dev/null
+++ b/packages/layers/src/line/models/line.ts
@@ -0,0 +1,120 @@
+import {
+  AttributeType,
+  gl,
+  IEncodeFeature,
+  ILayer,
+  ILayerModel,
+  IModel,
+  IModelUniform,
+} from '@l7/core';
+
+import BaseModel from '../../core/baseModel';
+import { LineTriangulation } from '../../core/triangulation';
+import line_frag from '../shaders/line_frag.glsl';
+import line_vert from '../shaders/line_vert.glsl';
+
+interface ILineLayerStyleOptions {
+  opacity: number;
+}
+export default class LineModel extends BaseModel {
+  public getUninforms(): IModelUniform {
+    const { opacity } = this.layer.getStyleOptions() as ILineLayerStyleOptions;
+    return {
+      u_opacity: opacity || 1.0,
+    };
+  }
+
+  public buildModels(): IModel[] {
+    return [
+      this.layer.buildLayerModel({
+        moduleName: 'line',
+        vertexShader: line_vert,
+        fragmentShader: line_frag,
+        triangulation: LineTriangulation,
+        blend: {
+          enable: true,
+          func: {
+            srcRGB: gl.SRC_ALPHA,
+            srcAlpha: 1,
+            dstRGB: gl.ONE_MINUS_SRC_ALPHA,
+            dstAlpha: 1,
+          },
+        },
+      }),
+    ];
+  }
+  protected registerBuiltinAttributes() {
+    // point layer size;
+    this.layer.styleAttributeService.registerStyleAttribute({
+      name: 'size',
+      type: AttributeType.Attribute,
+      descriptor: {
+        name: 'a_Size',
+        buffer: {
+          // give the WebGL driver a hint that this buffer may change
+          usage: gl.DYNAMIC_DRAW,
+          data: [],
+          type: gl.FLOAT,
+        },
+        size: 2,
+        update: (
+          feature: IEncodeFeature,
+          featureIdx: number,
+          vertex: number[],
+          attributeIdx: number,
+        ) => {
+          const { size } = feature;
+          return Array.isArray(size) ? [size[0], size[1]] : [size as number, 0];
+        },
+      },
+    });
+
+    // point layer size;
+    this.layer.styleAttributeService.registerStyleAttribute({
+      name: 'normal',
+      type: AttributeType.Attribute,
+      descriptor: {
+        name: 'a_Normal',
+        buffer: {
+          // give the WebGL driver a hint that this buffer may change
+          usage: gl.STATIC_DRAW,
+          data: [],
+          type: gl.FLOAT,
+        },
+        size: 3,
+        update: (
+          feature: IEncodeFeature,
+          featureIdx: number,
+          vertex: number[],
+          attributeIdx: number,
+          normal: number[],
+        ) => {
+          return normal;
+        },
+      },
+    });
+
+    this.layer.styleAttributeService.registerStyleAttribute({
+      name: 'miter',
+      type: AttributeType.Attribute,
+      descriptor: {
+        name: 'a_Miter',
+        buffer: {
+          // give the WebGL driver a hint that this buffer may change
+          usage: gl.DYNAMIC_DRAW,
+          data: [],
+          type: gl.FLOAT,
+        },
+        size: 1,
+        update: (
+          feature: IEncodeFeature,
+          featureIdx: number,
+          vertex: number[],
+          attributeIdx: number,
+        ) => {
+          return [vertex[4]];
+        },
+      },
+    });
+  }
+}
diff --git a/packages/layers/src/point/buffers/ExtrudeBuffer.ts b/packages/layers/src/point/buffers/ExtrudeBuffer.ts
deleted file mode 100644
index f0cd0d8d1a..0000000000
--- a/packages/layers/src/point/buffers/ExtrudeBuffer.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-// import BaseBuffer, {
-//   IBufferInfo,
-//   IEncodeFeature,
-//   Position,
-// } from '../../core/BaseBuffer';
-// import extrudePolygon, { IExtrudeGeomety } from '../shape/extrude';
-// import { geometryShape, ShapeType2D, ShapeType3D } from '../shape/Path';
-// interface IGeometryCache {
-//   [key: string]: IExtrudeGeomety;
-// }
-// export default class ExtrudeBuffer extends BaseBuffer {
-//   private indexOffset: number = 0;
-//   private verticesOffset: number = 0;
-//   private geometryCache: IGeometryCache;
-//   public buildFeatures() {
-//     const layerData = this.data as IEncodeFeature[];
-//     layerData.forEach((feature: IEncodeFeature) => {
-//       this.calculateFill(feature);
-//     });
-//   }
-
-//   protected calculateFeatures() {
-//     const layerData = this.data as IEncodeFeature[];
-//     this.geometryCache = {};
-//     this.verticesOffset = 0;
-//     this.indexOffset = 0;
-//     layerData.forEach((feature: IEncodeFeature) => {
-//       const { shape } = feature;
-//       const { positions, index } = this.getGeometry(shape as ShapeType3D);
-//       this.verticesCount += positions.length / 3;
-//       this.indexCount += index.length;
-//     });
-//   }
-//   protected initAttributes() {
-//     super.initAttributes();
-//     this.attributes.miters = new Float32Array(this.verticesCount * 3);
-//     this.attributes.normals = new Float32Array(this.verticesCount * 3);
-//     this.attributes.sizes = new Float32Array(this.verticesCount * 3);
-//   }
-//   private calculateFill(feature: IEncodeFeature) {
-//     const { coordinates, shape } = feature;
-//     const instanceGeometry = this.getGeometry(shape as ShapeType3D);
-//     const numPoint = instanceGeometry.positions.length / 3;
-//     feature.bufferInfo = {
-//       verticesOffset: this.verticesOffset,
-//       indexOffset: this.indexOffset,
-//       dimensions: 3,
-//     };
-//     this.encodeArray(feature, numPoint);
-//     this.attributes.miters.set(
-//       instanceGeometry.positions,
-//       this.verticesOffset * 3,
-//     );
-//     const indexArray = instanceGeometry.index.map((v) => {
-//       return v + this.verticesOffset;
-//     });
-//     this.indexArray.set(indexArray, this.indexOffset);
-//     const position: number[] = [];
-//     for (let i = 0; i < numPoint; i++) {
-//       const coor = coordinates as Position;
-//       position.push(coor[0], coor[1], coor[2] || 0);
-//     }
-//     this.attributes.positions.set(position, this.verticesOffset * 3);
-//     this.verticesOffset += numPoint;
-//     this.indexOffset += indexArray.length;
-//   }
-
-//   private getGeometry(shape: ShapeType3D): IExtrudeGeomety {
-//     if (this.geometryCache && this.geometryCache[shape]) {
-//       return this.geometryCache[shape];
-//     }
-//     const path = geometryShape[shape]
-//       ? geometryShape[shape]()
-//       : geometryShape.cylinder();
-//     const geometry = extrudePolygon([path]);
-//     this.geometryCache[shape] = geometry;
-//     return geometry;
-//   }
-// }
diff --git a/packages/layers/src/point/buffers/ImageBuffer.ts b/packages/layers/src/point/buffers/ImageBuffer.ts
deleted file mode 100644
index 03aef61af5..0000000000
--- a/packages/layers/src/point/buffers/ImageBuffer.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-// import BaseBuffer, { IEncodeFeature, Position } from '../../core/BaseBuffer';
-// export default class ImageBuffer extends BaseBuffer {
-//   protected calculateFeatures() {
-//     const layerData = this.data as IEncodeFeature[];
-//     this.verticesCount = layerData.length;
-//     this.indexCount = layerData.length;
-//   }
-//   protected buildFeatures() {
-//     const layerData = this.data as IEncodeFeature[];
-//     this.attributes.uv = new Float32Array(this.verticesCount * 2);
-//     layerData.forEach((item: IEncodeFeature, index: number) => {
-//       const { color = [0, 0, 0, 0], size, id, shape, coordinates } = item;
-//       const { x, y } = this.iconMap[shape as string] || { x: 0, y: 0 };
-//       const coor = coordinates as Position;
-//       this.attributes.positions.set(coor, index * 3);
-//       this.attributes.colors.set(color, index * 4);
-//       this.attributes.pickingIds.set([id as number], index);
-//       this.attributes.sizes.set([size as number], index); //
-//       this.attributes.uv.set([x, y], index * 2);
-//     });
-//   }
-// }
diff --git a/packages/layers/src/point/index.ts b/packages/layers/src/point/index.ts
index 5ff8f0ff9a..d2a556c092 100644
--- a/packages/layers/src/point/index.ts
+++ b/packages/layers/src/point/index.ts
@@ -1,18 +1,6 @@
-import {
-  AttributeType,
-  gl,
-  IEncodeFeature,
-  ILayer,
-  ILayerPlugin,
-  ILogService,
-  IStyleAttributeService,
-  lazyInject,
-  TYPES,
-} from '@l7/core';
+import { IEncodeFeature } from '@l7/core';
 import BaseLayer from '../core/BaseLayer';
-import { rgb2arr } from '../utils/color';
-import pointFillFrag from './shaders/fill_frag.glsl';
-import pointFillVert from './shaders/fill_vert.glsl';
+import PointModels, { PointType } from './models/index';
 interface IPointLayerStyleOptions {
   opacity: number;
   strokeWidth: number;
@@ -20,7 +8,6 @@ interface IPointLayerStyleOptions {
 }
 export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
   public name: string = 'PointLayer';
-
   protected getConfigSchema() {
     return {
       properties: {
@@ -32,4 +19,44 @@ export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
       },
     };
   }
+  protected renderModels() {
+    this.models.forEach((model) =>
+      model.draw({
+        uniforms: this.layerModel.getUninforms(),
+      }),
+    );
+    return this;
+  }
+
+  protected buildModels() {
+    const modelType = this.getModelType();
+    this.layerModel = new PointModels[modelType](this);
+    this.models = this.layerModel.buildModels();
+  }
+
+  private getModelType(): PointType {
+    // pointlayer
+    //  2D、 3d、 shape、image、text、normal、
+    const layerData = this.getEncodedData();
+    const { shape2d, shape3d } = this.configService.getConfig();
+    const iconMap = this.iconService.getIconMap();
+    const item = layerData.find((fe: IEncodeFeature) => {
+      return fe.hasOwnProperty('shape');
+    });
+    if (!item) {
+      return 'normal';
+    } else {
+      const shape = item.shape;
+      if (shape2d?.indexOf(shape as string) !== -1) {
+        return 'fill';
+      }
+      if (shape3d?.indexOf(shape as string) !== -1) {
+        return 'extrude';
+      }
+      if (iconMap.hasOwnProperty(shape as string)) {
+        return 'image';
+      }
+      return 'text';
+    }
+  }
 }
diff --git a/packages/layers/src/point/extrude.ts b/packages/layers/src/point/models/extrude.ts
similarity index 68%
rename from packages/layers/src/point/extrude.ts
rename to packages/layers/src/point/models/extrude.ts
index 82d4cf7ce3..0b7495f7b1 100644
--- a/packages/layers/src/point/extrude.ts
+++ b/packages/layers/src/point/models/extrude.ts
@@ -1,42 +1,29 @@
-import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core';
-import BaseLayer from '../core/BaseLayer';
-import { PointExtrudeTriangulation } from '../core/triangulation';
-import pointExtrudeFrag from './shaders/extrude_frag.glsl';
-import pointExtrudeVert from './shaders/extrude_vert.glsl';
+import {
+  AttributeType,
+  gl,
+  IEncodeFeature,
+  ILayer,
+  ILayerModel,
+  IModel,
+} from '@l7/core';
+import BaseModel from '../../core/baseModel';
+import { PointExtrudeTriangulation } from '../../core/triangulation';
+import pointExtrudeFrag from '../shaders/extrude_frag.glsl';
+import pointExtrudeVert from '../shaders/extrude_vert.glsl';
 interface IPointLayerStyleOptions {
   opacity: number;
 }
-export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
-  public name: string = 'PointLayer';
-
-  protected getConfigSchema() {
+export default class ExtrudeModel extends BaseModel {
+  public getUninforms() {
+    const { opacity } = this.layer.getStyleOptions() as IPointLayerStyleOptions;
     return {
-      properties: {
-        opacity: {
-          type: 'number',
-          minimum: 0,
-          maximum: 1,
-        },
-      },
+      u_opacity: opacity || 1.0,
     };
   }
 
-  protected renderModels() {
-    const { opacity } = this.getStyleOptions();
-    this.models.forEach((model) =>
-      model.draw({
-        uniforms: {
-          u_opacity: opacity || 1.0,
-        },
-      }),
-    );
-    return this;
-  }
-
-  protected buildModels() {
-    this.registerBuiltinAttributes(this);
-    this.models = [
-      this.buildLayerModel({
+  public buildModels(): IModel[] {
+    return [
+      this.layer.buildLayerModel({
         moduleName: 'pointExtrude',
         vertexShader: pointExtrudeVert,
         fragmentShader: pointExtrudeFrag,
@@ -53,10 +40,9 @@ export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
       }),
     ];
   }
-
-  private registerBuiltinAttributes(layer: ILayer) {
+  protected registerBuiltinAttributes() {
     // point layer size;
-    layer.styleAttributeService.registerStyleAttribute({
+    this.layer.styleAttributeService.registerStyleAttribute({
       name: 'size',
       type: AttributeType.Attribute,
       descriptor: {
@@ -93,7 +79,7 @@ export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
     });
 
     // point layer size;
-    layer.styleAttributeService.registerStyleAttribute({
+    this.layer.styleAttributeService.registerStyleAttribute({
       name: 'normal',
       type: AttributeType.Attribute,
       descriptor: {
@@ -116,7 +102,7 @@ export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
         },
       },
     });
-    layer.styleAttributeService.registerStyleAttribute({
+    this.layer.styleAttributeService.registerStyleAttribute({
       name: 'pos',
       type: AttributeType.Attribute,
       descriptor: {
diff --git a/packages/layers/src/point/fill.ts b/packages/layers/src/point/models/fill.ts
similarity index 61%
rename from packages/layers/src/point/fill.ts
rename to packages/layers/src/point/models/fill.ts
index a94fefbe69..2a1277a9b3 100644
--- a/packages/layers/src/point/fill.ts
+++ b/packages/layers/src/point/models/fill.ts
@@ -3,78 +3,52 @@ import {
   gl,
   IEncodeFeature,
   ILayer,
+  ILayerModel,
   ILayerPlugin,
   ILogService,
+  IModel,
   IStyleAttributeService,
   lazyInject,
   TYPES,
 } from '@l7/core';
-import BaseLayer from '../core/BaseLayer';
-import { rgb2arr } from '../utils/color';
-import pointFillFrag from './shaders/fill_frag.glsl';
-import pointFillVert from './shaders/fill_vert.glsl';
+import BaseModel from '../../core/baseModel';
+import { PointFillTriangulation } from '../../core/triangulation';
+import { rgb2arr } from '../../utils/color';
+import pointFillFrag from '../shaders/fill_frag.glsl';
+import pointFillVert from '../shaders/fill_vert.glsl';
 interface IPointLayerStyleOptions {
   opacity: number;
   strokeWidth: number;
   strokeColor: string;
 }
-export function PointTriangulation(feature: IEncodeFeature) {
-  const coordinates = feature.coordinates as number[];
-  return {
-    vertices: [...coordinates, ...coordinates, ...coordinates, ...coordinates],
-    extrude: [-1, -1, 1, -1, 1, 1, -1, 1],
-    indices: [0, 1, 2, 2, 3, 0],
-    size: coordinates.length,
-  };
-}
-export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
-  public name: string = 'PointLayer';
-
-  protected getConfigSchema() {
-    return {
-      properties: {
-        opacity: {
-          type: 'number',
-          minimum: 0,
-          maximum: 1,
-        },
-      },
-    };
-  }
-
-  protected renderModels() {
+export default class FillModel extends BaseModel {
+  public getUninforms() {
     const {
       opacity = 1,
       strokeColor = 'rgb(0,0,0,0)',
       strokeWidth = 1,
-    } = this.getStyleOptions();
-    this.models.forEach((model) =>
-      model.draw({
-        uniforms: {
-          u_opacity: opacity,
-          u_stroke_width: strokeWidth,
-          u_stroke_color: rgb2arr(strokeColor),
-        },
-      }),
-    );
-    return this;
+    } = this.layer.getStyleOptions() as IPointLayerStyleOptions;
+    return {
+      u_opacity: opacity,
+      u_stroke_width: strokeWidth,
+      u_stroke_color: rgb2arr(strokeColor),
+    };
   }
 
-  protected buildModels() {
-    this.registerBuiltinAttributes(this);
-    this.models = [
-      this.buildLayerModel({
+  public buildModels(): IModel[] {
+    return [
+      this.layer.buildLayerModel({
         moduleName: 'pointfill',
         vertexShader: pointFillVert,
         fragmentShader: pointFillFrag,
-        triangulation: PointTriangulation,
+        triangulation: PointFillTriangulation,
         depth: { enable: false },
       }),
     ];
   }
 
-  private registerBuiltinAttributes(layer: ILayer) {
-    layer.styleAttributeService.registerStyleAttribute({
+  protected registerBuiltinAttributes() {
+    this.layer.styleAttributeService.registerStyleAttribute({
       name: 'extrude',
       type: AttributeType.Attribute,
       descriptor: {
@@ -100,7 +74,7 @@ export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
     });
 
     // point layer size;
-    layer.styleAttributeService.registerStyleAttribute({
+    this.layer.styleAttributeService.registerStyleAttribute({
       name: 'size',
       type: AttributeType.Attribute,
       descriptor: {
@@ -125,7 +99,7 @@ export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
     });
 
     // point layer size;
-    layer.styleAttributeService.registerStyleAttribute({
+    this.layer.styleAttributeService.registerStyleAttribute({
       name: 'shape',
       type: AttributeType.Attribute,
       descriptor: {
@@ -144,7 +118,8 @@ export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
           attributeIdx: number,
         ) => {
           const { shape = 2 } = feature;
-          const shape2d = layer.configService.getConfig().shape2d as string[];
+          const shape2d = this.layer.configService.getConfig()
+            .shape2d as string[];
           const shapeIndex = shape2d.indexOf(shape as string);
           return [shapeIndex];
         },
diff --git a/packages/layers/src/point/image.ts b/packages/layers/src/point/models/image.ts
similarity index 58%
rename from packages/layers/src/point/image.ts
rename to packages/layers/src/point/models/image.ts
index 0112f7be08..569b7935d6 100644
--- a/packages/layers/src/point/image.ts
+++ b/packages/layers/src/point/models/image.ts
@@ -3,73 +3,44 @@ import {
   gl,
   IEncodeFeature,
   ILayer,
-  ILayerPlugin,
-  ILogService,
-  IStyleAttributeService,
+  ILayerModel,
+  IModel,
   ITexture2D,
-  lazyInject,
-  TYPES,
 } from '@l7/core';
-import BaseLayer from '../core/BaseLayer';
-import { PointImageTriangulation } from '../core/triangulation';
-import pointImageFrag from './shaders/image_frag.glsl';
-import pointImageVert from './shaders/image_vert.glsl';
+
+import BaseModel from '../../core/baseModel';
+import { PointImageTriangulation } from '../../core/triangulation';
+import pointImageFrag from '../shaders/image_frag.glsl';
+import pointImageVert from '../shaders/image_vert.glsl';
 interface IPointLayerStyleOptions {
   opacity: number;
 }
-export function PointTriangulation(feature: IEncodeFeature) {
-  const coordinates = feature.coordinates as number[];
-  return {
-    vertices: [...coordinates, ...coordinates, ...coordinates, ...coordinates],
-    extrude: [-1, -1, 1, -1, 1, 1, -1, 1],
-    indices: [0, 1, 2, 2, 3, 0],
-    size: coordinates.length,
-  };
-}
-export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
-  public name: string = 'PointLayer';
+
+export default class ImageModel extends BaseModel {
   private texture: ITexture2D;
-  protected getConfigSchema() {
+
+  public getUninforms() {
+    const { opacity } = this.layer.getStyleOptions() as IPointLayerStyleOptions;
     return {
-      properties: {
-        opacity: {
-          type: 'number',
-          minimum: 0,
-          maximum: 1,
-        },
-      },
+      u_opacity: opacity || 1.0,
+      u_texture: this.texture,
+      u_textSize: [1024, this.iconService.canvasHeight || 128],
     };
   }
 
-  protected renderModels() {
-    const { opacity } = this.getStyleOptions();
-    const { createTexture2D } = this.rendererService;
-    this.models.forEach((model) =>
-      model.draw({
-        uniforms: {
-          u_opacity: opacity || 1.0,
-          u_texture: this.texture,
-          u_textSize: [1024, this.iconService.canvasHeight || 128],
-        },
-      }),
-    );
-
-    return this;
-  }
-
-  protected buildModels() {
-    this.registerBuiltinAttributes(this);
+  public buildModels(): IModel[] {
+    this.registerBuiltinAttributes();
     this.updateTexture();
     this.iconService.on('imageUpdate', () => {
       this.updateTexture();
-      this.renderModels();
+      this.layer.render(); // TODO 调用全局render
     });
-    this.models = [
-      this.buildLayerModel({
+    return [
+      this.layer.buildLayerModel({
         moduleName: 'pointImage',
         vertexShader: pointImageVert,
         fragmentShader: pointImageFrag,
-        triangulation: PointTriangulation,
+        triangulation: PointImageTriangulation,
         primitive: gl.POINTS,
         depth: { enable: false },
         blend: {
@@ -85,9 +56,9 @@ export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
     ];
   }
 
-  private registerBuiltinAttributes(layer: ILayer) {
+  protected registerBuiltinAttributes() {
     // point layer size;
-    layer.styleAttributeService.registerStyleAttribute({
+    this.layer.styleAttributeService.registerStyleAttribute({
       name: 'size',
       type: AttributeType.Attribute,
       descriptor: {
@@ -112,7 +83,7 @@ export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
     });
 
     // point layer size;
-    layer.styleAttributeService.registerStyleAttribute({
+    this.layer.styleAttributeService.registerStyleAttribute({
       name: 'uv',
       type: AttributeType.Attribute,
       descriptor: {
@@ -139,6 +110,7 @@ export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
       },
     });
   }
+
   private updateTexture() {
     const { createTexture2D } = this.rendererService;
     this.texture = createTexture2D({
diff --git a/packages/layers/src/point/models/index.ts b/packages/layers/src/point/models/index.ts
new file mode 100644
index 0000000000..8dd5b347a6
--- /dev/null
+++ b/packages/layers/src/point/models/index.ts
@@ -0,0 +1,17 @@
+import { ILayerModel } from '@l7/core';
+import ExtrudeModel from './extrude';
+import FillModel from './fill';
+import IMageModel from './image';
+import NormalModel from './normal';
+
+export type PointType = 'fill' | 'image' | 'normal' | 'extrude' | 'text';
+
+const PointModels: { [key in PointType]: any } = {
+  fill: FillModel,
+  image: IMageModel,
+  normal: NormalModel,
+  extrude: ExtrudeModel,
+  text: null,
+};
+
+export default PointModels;
diff --git a/packages/layers/src/point/normal.ts b/packages/layers/src/point/models/normal.ts
similarity index 58%
rename from packages/layers/src/point/normal.ts
rename to packages/layers/src/point/models/normal.ts
index 85c725619b..1d4dd89172 100644
--- a/packages/layers/src/point/normal.ts
+++ b/packages/layers/src/point/models/normal.ts
@@ -3,16 +3,15 @@ import {
   gl,
   IEncodeFeature,
   ILayer,
-  ILayerPlugin,
-  ILogService,
-  IStyleAttributeService,
-  lazyInject,
-  TYPES,
+  ILayerModel,
+  IModel,
 } from '@l7/core';
-import BaseLayer from '../core/BaseLayer';
-import { rgb2arr } from '../utils/color';
-import normalFrag from './shaders/normal_frag.glsl';
-import normalVert from './shaders/normal_vert.glsl';
+
+import BaseModel from '../../core/baseModel';
+import { rgb2arr } from '../../utils/color';
+import normalFrag from '../shaders/normal_frag.glsl';
+import normalVert from '../shaders/normal_vert.glsl';
+
 interface IPointLayerStyleOptions {
   opacity: number;
   strokeWidth: number;
@@ -26,45 +25,24 @@ export function PointTriangulation(feature: IEncodeFeature) {
     size: coordinates.length,
   };
 }
-export default class PointNormalLayer extends BaseLayer<
-  IPointLayerStyleOptions
-> {
-  public name: string = 'PointLayer';
 
-  protected getConfigSchema() {
-    return {
-      properties: {
-        opacity: {
-          type: 'number',
-          minimum: 0,
-          maximum: 1,
-        },
-      },
-    };
-  }
-
-  protected renderModels() {
+export default class NormalModel extends BaseModel {
+  public getUninforms() {
     const {
       opacity = 1,
       strokeColor = 'rgb(0,0,0,0)',
       strokeWidth = 1,
-    } = this.getStyleOptions();
-    this.models.forEach((model) =>
-      model.draw({
-        uniforms: {
-          u_opacity: opacity,
-          u_stroke_width: strokeWidth,
-          u_stroke_color: rgb2arr(strokeColor),
-        },
-      }),
-    );
-    return this;
+    } = this.layer.getStyleOptions() as IPointLayerStyleOptions;
+    return {
+      u_opacity: opacity,
+      u_stroke_width: strokeWidth,
+      u_stroke_color: rgb2arr(strokeColor),
+    };
   }
 
-  protected buildModels() {
-    this.registerBuiltinAttributes(this);
-    this.models = [
-      this.buildLayerModel({
+  public buildModels(): IModel[] {
+    return [
+      this.layer.buildLayerModel({
         moduleName: 'normalpoint',
         vertexShader: normalVert,
         fragmentShader: normalFrag,
@@ -84,9 +62,9 @@ export default class PointNormalLayer extends BaseLayer<
     ];
   }
 
-  private registerBuiltinAttributes(layer: ILayer) {
+  protected registerBuiltinAttributes() {
     // point layer size;
-    layer.styleAttributeService.registerStyleAttribute({
+    this.layer.styleAttributeService.registerStyleAttribute({
       name: 'size',
       type: AttributeType.Attribute,
       descriptor: {
diff --git a/packages/layers/src/point/models/text.ts b/packages/layers/src/point/models/text.ts
new file mode 100644
index 0000000000..202557d9e5
--- /dev/null
+++ b/packages/layers/src/point/models/text.ts
@@ -0,0 +1,30 @@
+import {
+  AttributeType,
+  gl,
+  IEncodeFeature,
+  ILayer,
+  ILayerModel,
+  IModel,
+} from '@l7/core';
+import BaseLayer from '../core/BaseLayer';
+import { PointExtrudeTriangulation } from '../core/triangulation';
+import pointExtrudeFrag from './shaders/extrude_frag.glsl';
+import pointExtrudeVert from './shaders/extrude_vert.glsl';
+
+export default class ExtrudeModel implements ILayerModel {
+  private layer: ILayer;
+  constructor(layer: ILayer) {
+    this.layer = layer;
+    this.registerBuiltinAttributes();
+  }
+  public getUninforms() {
+    throw new Error('Method not implemented.');
+  }
+
+  public buildModels(): IModel[] {
+    throw new Error('Method not implemented.');
+  }
+  private registerBuiltinAttributes() {
+    throw new Error('Method not implemented.');
+  }
+}
diff --git a/packages/layers/src/polygon/index.ts b/packages/layers/src/polygon/index.ts
index 715caf4cf2..52e663069b 100644
--- a/packages/layers/src/polygon/index.ts
+++ b/packages/layers/src/polygon/index.ts
@@ -1,25 +1,11 @@
 import { IEncodeFeature } from '@l7/core';
-import earcut from 'earcut';
 import BaseLayer from '../core/BaseLayer';
-import polygon_frag from './shaders/polygon_frag.glsl';
-import polygon_vert from './shaders/polygon_vert.glsl';
+import PolygonModels, { PolygonModelType } from './models/';
 
 interface IPolygonLayerStyleOptions {
   opacity: number;
 }
 
-export function polygonTriangulation(feature: IEncodeFeature) {
-  const { coordinates } = feature;
-  const flattengeo = earcut.flatten(coordinates as number[][][]);
-  const { vertices, dimensions, holes } = flattengeo;
-
-  return {
-    indices: earcut(vertices, holes, dimensions),
-    vertices,
-    size: dimensions,
-  };
-}
-
 export default class PolygonLayer extends BaseLayer<IPolygonLayerStyleOptions> {
   public name: string = 'PolygonLayer';
 
@@ -36,26 +22,25 @@ export default class PolygonLayer extends BaseLayer<IPolygonLayerStyleOptions> {
   }
 
   protected renderModels() {
-    const { opacity } = this.getStyleOptions();
     this.models.forEach((model) =>
       model.draw({
-        uniforms: {
-          u_opacity: opacity || 1.0,
-        },
+        uniforms: this.layerModel.getUninforms(),
       }),
     );
     return this;
   }
 
   protected buildModels() {
-    this.models = [
-      this.buildLayerModel({
-        moduleName: 'polygon',
-        vertexShader: polygon_vert,
-        fragmentShader: polygon_frag,
-        triangulation: polygonTriangulation,
-        depth: { enable: false },
-      }),
-    ];
+    const shape = this.getModelType();
+    this.layerModel = new PolygonModels[shape](this);
+    this.models = this.layerModel.buildModels();
+  }
+
+  private getModelType(): PolygonModelType {
+    const shapeAttribute = this.styleAttributeService.getLayerStyleAttribute(
+      'shape',
+    );
+    const shape = shapeAttribute?.scale?.field as PolygonModelType;
+    return shape || 'fill';
   }
 }
diff --git a/packages/layers/src/polygon/models/extrude.ts b/packages/layers/src/polygon/models/extrude.ts
new file mode 100644
index 0000000000..ac4dafc960
--- /dev/null
+++ b/packages/layers/src/polygon/models/extrude.ts
@@ -0,0 +1,92 @@
+import {
+  AttributeType,
+  gl,
+  IEncodeFeature,
+  ILayer,
+  ILayerModel,
+  ILayerPlugin,
+  ILogService,
+  IModel,
+  IStyleAttributeService,
+  lazyInject,
+  TYPES,
+} from '@l7/core';
+import BaseModel from '../../core/baseModel';
+import { PolygonExtrudeTriangulation } from '../../core/triangulation';
+import polygonExtrudeFrag from '../shaders/polygon_extrude_frag.glsl';
+import polygonExtrudeVert from '../shaders/polygon_extrude_vert.glsl';
+interface IPolygonLayerStyleOptions {
+  opacity: number;
+}
+export default class ExtrudeModel extends BaseModel {
+  public getUninforms() {
+    const {
+      opacity = 1,
+    } = this.layer.getStyleOptions() as IPolygonLayerStyleOptions;
+    return {
+      u_opacity: opacity,
+    };
+  }
+
+  public buildModels(): IModel[] {
+    return [
+      this.layer.buildLayerModel({
+        moduleName: 'polygonExtrude',
+        vertexShader: polygonExtrudeVert,
+        fragmentShader: polygonExtrudeFrag,
+        triangulation: PolygonExtrudeTriangulation,
+      }),
+    ];
+  }
+
+  protected registerBuiltinAttributes() {
+    // point layer size;
+    this.layer.styleAttributeService.registerStyleAttribute({
+      name: 'normal',
+      type: AttributeType.Attribute,
+      descriptor: {
+        name: 'a_Normal',
+        buffer: {
+          // give the WebGL driver a hint that this buffer may change
+          usage: gl.STATIC_DRAW,
+          data: [],
+          type: gl.FLOAT,
+        },
+        size: 3,
+        update: (
+          feature: IEncodeFeature,
+          featureIdx: number,
+          vertex: number[],
+          attributeIdx: number,
+          normal: number[],
+        ) => {
+          return normal;
+        },
+      },
+    });
+
+    this.layer.styleAttributeService.registerStyleAttribute({
+      name: 'size',
+      type: AttributeType.Attribute,
+      descriptor: {
+        name: 'a_Size',
+        buffer: {
+          // give the WebGL driver a hint that this buffer may change
+          usage: gl.DYNAMIC_DRAW,
+          data: [],
+          type: gl.FLOAT,
+        },
+        size: 1,
+        update: (
+          feature: IEncodeFeature,
+          featureIdx: number,
+          vertex: number[],
+          attributeIdx: number,
+        ) => {
+          const { size } = feature;
+          return Array.isArray(size) ? [size[0]] : [size as number];
+        },
+      },
+    });
+  }
+}
diff --git a/packages/layers/src/polygon/models/fill.ts b/packages/layers/src/polygon/models/fill.ts
new file mode 100644
index 0000000000..26c88f60aa
--- /dev/null
+++ b/packages/layers/src/polygon/models/fill.ts
@@ -0,0 +1,47 @@
+import {
+  AttributeType,
+  gl,
+  IEncodeFeature,
+  ILayer,
+  ILayerModel,
+  ILayerPlugin,
+  ILogService,
+  IModel,
+  IStyleAttributeService,
+  lazyInject,
+  TYPES,
+} from '@l7/core';
+import BaseModel from '../../core/baseModel';
+import { polygonTriangulation } from '../../core/triangulation';
+import polygon_frag from '../shaders/polygon_frag.glsl';
+import polygon_vert from '../shaders/polygon_vert.glsl';
+
+interface IPolygonLayerStyleOptions {
+  opacity: number;
+}
+export default class FillModel extends BaseModel {
+  public getUninforms() {
+    const {
+      opacity = 1,
+    } = this.layer.getStyleOptions() as IPolygonLayerStyleOptions;
+    return {
+      u_opacity: opacity,
+    };
+  }
+
+  public buildModels(): IModel[] {
+    return [
+      this.layer.buildLayerModel({
+        moduleName: 'polygon',
+        vertexShader: polygon_vert,
+        fragmentShader: polygon_frag,
+        triangulation: polygonTriangulation,
+        depth: { enable: false },
+      }),
+    ];
+  }
+
+  protected registerBuiltinAttributes() {
+    // point layer size;
+  }
+}
diff --git a/packages/layers/src/polygon/models/index.ts b/packages/layers/src/polygon/models/index.ts
new file mode 100644
index 0000000000..cf0495ccca
--- /dev/null
+++ b/packages/layers/src/polygon/models/index.ts
@@ -0,0 +1,11 @@
+import ExtrudeModel from './extrude';
+import FillModel from './fill';
+
+export type PolygonModelType = 'fill' | 'extrude';
+
+const PolygonModels: { [key in PolygonModelType]: any } = {
+  fill: FillModel,
+  extrude: ExtrudeModel,
+};
+
+export default PolygonModels;
diff --git a/packages/layers/src/polygon/polygon3D.ts b/packages/layers/src/polygon/polygon3D.ts
index afdb5d86ed..a320d45145 100644
--- a/packages/layers/src/polygon/polygon3D.ts
+++ b/packages/layers/src/polygon/polygon3D.ts
@@ -1,8 +1,8 @@
 import { AttributeType, gl, IEncodeFeature, ILayer } from '@l7/core';
 import BaseLayer from '../core/BaseLayer';
 import { PolygonExtrudeTriangulation } from '../core/triangulation';
-import pointExtrudeFrag from './shaders/polygon_extrude_frag.glsl';
-import pointExtrudeVert from './shaders/polygon_extrude_vert.glsl';
+import polygonExtrudeFrag from './shaders/polygon_extrude_frag.glsl';
+import polygonExtrudeVert from './shaders/polygon_extrude_vert.glsl';
 interface IPointLayerStyleOptions {
   opacity: number;
 }
@@ -38,8 +38,8 @@ export default class PolygonLayer extends BaseLayer<IPointLayerStyleOptions> {
     this.models = [
       this.buildLayerModel({
         moduleName: 'polygonExtrude',
-        vertexShader: pointExtrudeVert,
-        fragmentShader: pointExtrudeFrag,
+        vertexShader: polygonExtrudeVert,
+        fragmentShader: polygonExtrudeFrag,
         triangulation: PolygonExtrudeTriangulation,
       }),
     ];