aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/MapImageService/MapImageService.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Services/MapImageService/MapImageService.cs155
1 files changed, 125 insertions, 30 deletions
diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs
index a816411..fcace3a 100644
--- a/OpenSim/Services/MapImageService/MapImageService.cs
+++ b/OpenSim/Services/MapImageService/MapImageService.cs
@@ -69,6 +69,8 @@ namespace OpenSim.Services.MapImageService
69 private static bool m_Initialized = false; 69 private static bool m_Initialized = false;
70 private static string m_WaterTileFile = string.Empty; 70 private static string m_WaterTileFile = string.Empty;
71 private static Color m_Watercolor = Color.FromArgb(29, 71, 95); 71 private static Color m_Watercolor = Color.FromArgb(29, 71, 95);
72 private static Bitmap m_WaterBitmap = null;
73 private static byte[] m_WaterBytes = null;
72 74
73 public MapImageService(IConfigSource config) 75 public MapImageService(IConfigSource config)
74 { 76 {
@@ -91,6 +93,18 @@ namespace OpenSim.Services.MapImageService
91 Bitmap waterTile = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH); 93 Bitmap waterTile = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH);
92 FillImage(waterTile, m_Watercolor); 94 FillImage(waterTile, m_Watercolor);
93 waterTile.Save(m_WaterTileFile, ImageFormat.Jpeg); 95 waterTile.Save(m_WaterTileFile, ImageFormat.Jpeg);
96 m_WaterBitmap = waterTile;
97 }
98
99 if (File.Exists(m_WaterTileFile))
100 {
101 m_WaterBitmap = new Bitmap(m_WaterTileFile);
102 using (MemoryStream ms = new MemoryStream())
103 {
104 m_WaterBitmap.Save(ms,ImageFormat.Jpeg);
105 ms.Seek(0, SeekOrigin.Begin);
106 m_WaterBytes = ms.ToArray();
107 }
94 } 108 }
95 } 109 }
96 } 110 }
@@ -98,10 +112,10 @@ namespace OpenSim.Services.MapImageService
98 112
99 #region IMapImageService 113 #region IMapImageService
100 114
101 public bool AddMapTile(int x, int y, byte[] imageData, out string reason) 115 public bool AddMapTile(int x, int y, byte[] imageData, UUID scopeID, out string reason)
102 { 116 {
103 reason = string.Empty; 117 reason = string.Empty;
104 string fileName = GetFileName(1, x, y); 118 string fileName = GetFileName(1, x, y, scopeID);
105 119
106 lock (m_Sync) 120 lock (m_Sync)
107 { 121 {
@@ -117,6 +131,7 @@ namespace OpenSim.Services.MapImageService
117 return false; 131 return false;
118 } 132 }
119 } 133 }
134<<<<<<< HEAD
120 135
121 return UpdateMultiResolutionFilesAsync(x, y, out reason); 136 return UpdateMultiResolutionFilesAsync(x, y, out reason);
122 } 137 }
@@ -125,24 +140,49 @@ namespace OpenSim.Services.MapImageService
125 { 140 {
126 reason = String.Empty; 141 reason = String.Empty;
127 string fileName = GetFileName(1, x, y); 142 string fileName = GetFileName(1, x, y);
143=======
144
145 return UpdateMultiResolutionFiles(x, y, scopeID, out reason);
146 }
147
148 public bool RemoveMapTile(int x, int y, UUID scopeID, out string reason)
149 {
150 reason = String.Empty;
151 string fileName = GetFileName(1, x, y, scopeID);
152>>>>>>> avn/ubitvar
128 153
129 lock (m_Sync) 154 lock (m_Sync)
130 { 155 {
131 try 156 try
157<<<<<<< HEAD
132 { 158 {
133 File.Delete(fileName); 159 File.Delete(fileName);
134 } 160 }
135 catch (Exception e) 161 catch (Exception e)
136 { 162 {
163=======
164 {
165 File.Delete(fileName);
166 }
167 catch (Exception e)
168 {
169>>>>>>> avn/ubitvar
137 m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to save delete file {0}: {1}", fileName, e); 170 m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to save delete file {0}: {1}", fileName, e);
138 reason = e.Message; 171 reason = e.Message;
139 return false; 172 return false;
140 } 173 }
141 } 174 }
175<<<<<<< HEAD
142 176
143 return UpdateMultiResolutionFilesAsync(x, y, out reason); 177 return UpdateMultiResolutionFilesAsync(x, y, out reason);
144 } 178 }
145 179
180=======
181
182 return UpdateMultiResolutionFiles(x, y, scopeID, out reason);
183 }
184
185>>>>>>> avn/ubitvar
146 // When large varregions start up, they can send piles of new map tiles. This causes 186 // When large varregions start up, they can send piles of new map tiles. This causes
147 // this multi-resolution routine to be called a zillion times an causes much CPU 187 // this multi-resolution routine to be called a zillion times an causes much CPU
148 // time to be spent creating multi-resolution tiles that will be replaced when 188 // time to be spent creating multi-resolution tiles that will be replaced when
@@ -151,6 +191,7 @@ namespace OpenSim.Services.MapImageService
151 { 191 {
152 public int xx; 192 public int xx;
153 public int yy; 193 public int yy;
194<<<<<<< HEAD
154 public mapToMultiRez(int pX, int pY) 195 public mapToMultiRez(int pX, int pY)
155 { 196 {
156 xx = pX; 197 xx = pX;
@@ -168,6 +209,29 @@ namespace OpenSim.Services.MapImageService
168 if (multiRezToBuild.Count == 1) 209 if (multiRezToBuild.Count == 1)
169 Util.FireAndForget( 210 Util.FireAndForget(
170 DoUpdateMultiResolutionFilesAsync, null, "MapImageService.DoUpdateMultiResolutionFilesAsync"); 211 DoUpdateMultiResolutionFilesAsync, null, "MapImageService.DoUpdateMultiResolutionFilesAsync");
212=======
213 public UUID scopeID;
214 public mapToMultiRez(int pX, int pY, UUID pscopeID)
215 {
216 xx = pX;
217 yy = pY;
218 scopeID = pscopeID;
219 }
220 };
221 private Queue<mapToMultiRez> multiRezToBuild = new Queue<mapToMultiRez>();
222
223 private bool UpdateMultiResolutionFiles(int x, int y, UUID scopeID, out string reason)
224 {
225 reason = String.Empty;
226
227 lock (multiRezToBuild)
228 {
229 // m_log.DebugFormat("{0} UpdateMultiResolutionFilesAsync: scheduling update for <{1},{2}>", LogHeader, x, y);
230 multiRezToBuild.Enqueue(new mapToMultiRez(x, y, scopeID));
231 if (multiRezToBuild.Count == 1)
232 Util.FireAndForget(
233 DoUpdateMultiResolutionFilesAsync);
234>>>>>>> avn/ubitvar
171 } 235 }
172 236
173 return true; 237 return true;
@@ -175,10 +239,15 @@ namespace OpenSim.Services.MapImageService
175 239
176 private void DoUpdateMultiResolutionFilesAsync(object o) 240 private void DoUpdateMultiResolutionFilesAsync(object o)
177 { 241 {
242<<<<<<< HEAD
178 // This sleep causes the FireAndForget thread to be different than the invocation thread. 243 // This sleep causes the FireAndForget thread to be different than the invocation thread.
179 // It also allows other tiles to be uploaded so the multi-rez images are more likely 244 // It also allows other tiles to be uploaded so the multi-rez images are more likely
180 // to be correct. 245 // to be correct.
181 Thread.Sleep(1 * 1000); 246 Thread.Sleep(1 * 1000);
247=======
248 // let acumulate large region tiles
249 Thread.Sleep(60 * 1000); // large regions take time to upload tiles
250>>>>>>> avn/ubitvar
182 251
183 while (multiRezToBuild.Count > 0) 252 while (multiRezToBuild.Count > 0)
184 { 253 {
@@ -192,20 +261,35 @@ namespace OpenSim.Services.MapImageService
192 { 261 {
193 int x = toMultiRez.xx; 262 int x = toMultiRez.xx;
194 int y = toMultiRez.yy; 263 int y = toMultiRez.yy;
264<<<<<<< HEAD
265 // m_log.DebugFormat("{0} DoUpdateMultiResolutionFilesAsync: doing build for <{1},{2}>", LogHeader, x, y);
266
267=======
268 UUID scopeID = toMultiRez.scopeID;
195 // m_log.DebugFormat("{0} DoUpdateMultiResolutionFilesAsync: doing build for <{1},{2}>", LogHeader, x, y); 269 // m_log.DebugFormat("{0} DoUpdateMultiResolutionFilesAsync: doing build for <{1},{2}>", LogHeader, x, y);
196 270
271 int width = 1;
272>>>>>>> avn/ubitvar
197 // Stitch seven more aggregate tiles together 273 // Stitch seven more aggregate tiles together
198 for (uint zoomLevel = 2; zoomLevel <= ZOOM_LEVELS; zoomLevel++) 274 for (uint zoomLevel = 2; zoomLevel <= ZOOM_LEVELS; zoomLevel++)
199 { 275 {
200 // Calculate the width (in full resolution tiles) and bottom-left 276 // Calculate the width (in full resolution tiles) and bottom-left
201 // corner of the current zoom level 277 // corner of the current zoom level
278<<<<<<< HEAD
202 int width = (int)Math.Pow(2, (double)(zoomLevel - 1)); 279 int width = (int)Math.Pow(2, (double)(zoomLevel - 1));
280=======
281 width *= 2;
282>>>>>>> avn/ubitvar
203 int x1 = x - (x % width); 283 int x1 = x - (x % width);
204 int y1 = y - (y % width); 284 int y1 = y - (y % width);
205 285
206 lock (m_Sync) // must lock the reading and writing of the maptile files 286 lock (m_Sync) // must lock the reading and writing of the maptile files
207 { 287 {
288<<<<<<< HEAD
208 if (!CreateTile(zoomLevel, x1, y1)) 289 if (!CreateTile(zoomLevel, x1, y1))
290=======
291 if (!CreateTile(zoomLevel, x1, y1, scopeID))
292>>>>>>> avn/ubitvar
209 { 293 {
210 m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to create tile for {0},{1} at zoom level {1}", x, y, zoomLevel); 294 m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to create tile for {0},{1} at zoom level {1}", x, y, zoomLevel);
211 return; 295 return;
@@ -214,25 +298,29 @@ namespace OpenSim.Services.MapImageService
214 } 298 }
215 } 299 }
216 } 300 }
301<<<<<<< HEAD
217 302
303=======
304>>>>>>> avn/ubitvar
218 return; 305 return;
219 } 306 }
220 307
221 public byte[] GetMapTile(string fileName, out string format) 308 public byte[] GetMapTile(string fileName, UUID scopeID, out string format)
222 { 309 {
223// m_log.DebugFormat("[MAP IMAGE SERVICE]: Getting map tile {0}", fileName); 310// m_log.DebugFormat("[MAP IMAGE SERVICE]: Getting map tile {0}", fileName);
224 311
225 format = ".jpg"; 312 format = ".jpg";
226 string fullName = Path.Combine(m_TilesStoragePath, fileName); 313 string fullName = Path.Combine(m_TilesStoragePath, scopeID.ToString());
314 fullName = Path.Combine(fullName, fileName);
227 if (File.Exists(fullName)) 315 if (File.Exists(fullName))
228 { 316 {
229 format = Path.GetExtension(fileName).ToLower(); 317 format = Path.GetExtension(fileName).ToLower();
230 //m_log.DebugFormat("[MAP IMAGE SERVICE]: Found file {0}, extension {1}", fileName, format); 318 //m_log.DebugFormat("[MAP IMAGE SERVICE]: Found file {0}, extension {1}", fileName, format);
231 return File.ReadAllBytes(fullName); 319 return File.ReadAllBytes(fullName);
232 } 320 }
233 else if (File.Exists(m_WaterTileFile)) 321 else if (m_WaterBytes != null)
234 { 322 {
235 return File.ReadAllBytes(m_WaterTileFile); 323 return (byte[])m_WaterBytes.Clone();
236 } 324 }
237 else 325 else
238 { 326 {
@@ -244,10 +332,12 @@ namespace OpenSim.Services.MapImageService
244 #endregion 332 #endregion
245 333
246 334
247 private string GetFileName(uint zoomLevel, int x, int y) 335 private string GetFileName(uint zoomLevel, int x, int y, UUID scopeID)
248 { 336 {
249 string extension = "jpg"; 337 string extension = "jpg";
250 return Path.Combine(m_TilesStoragePath, string.Format("map-{0}-{1}-{2}-objects.{3}", zoomLevel, x, y, extension)); 338 string path = Path.Combine(m_TilesStoragePath, scopeID.ToString());
339 Directory.CreateDirectory(path);
340 return Path.Combine(path, string.Format("map-{0}-{1}-{2}-objects.{3}", zoomLevel, x, y, extension));
251 } 341 }
252 342
253 private Bitmap GetInputTileImage(string fileName) 343 private Bitmap GetInputTileImage(string fileName)
@@ -276,7 +366,7 @@ namespace OpenSim.Services.MapImageService
276 { 366 {
277 // Create a new output tile with a transparent background 367 // Create a new output tile with a transparent background
278 Bitmap bm = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH, PixelFormat.Format24bppRgb); 368 Bitmap bm = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH, PixelFormat.Format24bppRgb);
279 bm.MakeTransparent(); 369 //bm.MakeTransparent(); // 24bpp does not have transparency, this whould make it 32bpp
280 return bm; 370 return bm;
281 } 371 }
282 } 372 }
@@ -288,7 +378,7 @@ namespace OpenSim.Services.MapImageService
288 return null; 378 return null;
289 } 379 }
290 380
291 private bool CreateTile(uint zoomLevel, int x, int y) 381 private bool CreateTile(uint zoomLevel, int x, int y, UUID scopeID)
292 { 382 {
293// m_log.DebugFormat("[MAP IMAGE SERVICE]: Create tile for {0} {1}, zoom {2}", x, y, zoomLevel); 383// m_log.DebugFormat("[MAP IMAGE SERVICE]: Create tile for {0} {1}, zoom {2}", x, y, zoomLevel);
294 int prevWidth = (int)Math.Pow(2, (double)zoomLevel - 2); 384 int prevWidth = (int)Math.Pow(2, (double)zoomLevel - 2);
@@ -303,55 +393,60 @@ namespace OpenSim.Services.MapImageService
303 int yOut = y - (y % thisWidth); 393 int yOut = y - (y % thisWidth);
304 394
305 // Try to open the four input tiles from the previous zoom level 395 // Try to open the four input tiles from the previous zoom level
306 Bitmap inputBL = GetInputTileImage(GetFileName(zoomLevel - 1, xIn, yIn)); 396 Bitmap inputBL = GetInputTileImage(GetFileName(zoomLevel - 1, xIn, yIn, scopeID));
307 Bitmap inputBR = GetInputTileImage(GetFileName(zoomLevel - 1, xIn + prevWidth, yIn)); 397 Bitmap inputBR = GetInputTileImage(GetFileName(zoomLevel - 1, xIn + prevWidth, yIn, scopeID));
308 Bitmap inputTL = GetInputTileImage(GetFileName(zoomLevel - 1, xIn, yIn + prevWidth)); 398 Bitmap inputTL = GetInputTileImage(GetFileName(zoomLevel - 1, xIn, yIn + prevWidth, scopeID));
309 Bitmap inputTR = GetInputTileImage(GetFileName(zoomLevel - 1, xIn + prevWidth, yIn + prevWidth)); 399 Bitmap inputTR = GetInputTileImage(GetFileName(zoomLevel - 1, xIn + prevWidth, yIn + prevWidth, scopeID));
310 400
311 // Open the output tile (current zoom level) 401 // Open the output tile (current zoom level)
312 string outputFile = GetFileName(zoomLevel, xOut, yOut); 402 string outputFile = GetFileName(zoomLevel, xOut, yOut, scopeID);
313 Bitmap output = GetOutputTileImage(outputFile); 403
314 if (output == null) 404 int ntiles = 0;
315 return false; 405 Bitmap output = (Bitmap)m_WaterBitmap.Clone();
316 FillImage(output, m_Watercolor);
317 406
318 if (inputBL != null) 407 if (inputBL != null)
319 { 408 {
320 ImageCopyResampled(output, inputBL, 0, HALF_WIDTH, 0, 0); 409 ImageCopyResampled(output, inputBL, 0, HALF_WIDTH, 0, 0);
321 inputBL.Dispose(); 410 inputBL.Dispose();
411 ntiles++;
322 } 412 }
323 if (inputBR != null) 413 if (inputBR != null)
324 { 414 {
325 ImageCopyResampled(output, inputBR, HALF_WIDTH, HALF_WIDTH, 0, 0); 415 ImageCopyResampled(output, inputBR, HALF_WIDTH, HALF_WIDTH, 0, 0);
326 inputBR.Dispose(); 416 inputBR.Dispose();
417 ntiles++;
327 } 418 }
328 if (inputTL != null) 419 if (inputTL != null)
329 { 420 {
330 ImageCopyResampled(output, inputTL, 0, 0, 0, 0); 421 ImageCopyResampled(output, inputTL, 0, 0, 0, 0);
331 inputTL.Dispose(); 422 inputTL.Dispose();
423 ntiles++;
332 } 424 }
333 if (inputTR != null) 425 if (inputTR != null)
334 { 426 {
335 ImageCopyResampled(output, inputTR, HALF_WIDTH, 0, 0, 0); 427 ImageCopyResampled(output, inputTR, HALF_WIDTH, 0, 0, 0);
336 inputTR.Dispose(); 428 inputTR.Dispose();
429 ntiles++;
337 } 430 }
338 431
339 // Write the modified output 432 // Write the modified output
340 try 433 if (ntiles == 0)
434 File.Delete(outputFile);
435
436 else
341 { 437 {
342 using (Bitmap final = new Bitmap(output)) 438
439 try
343 { 440 {
344 output.Dispose(); 441 output.Save(outputFile, ImageFormat.Jpeg);
345 final.Save(outputFile, ImageFormat.Jpeg);
346 } 442 }
347 } 443 catch (Exception e)
348 catch (Exception e) 444 {
349 { 445 m_log.WarnFormat("[MAP IMAGE SERVICE]: Oops on saving {0} {1}", outputFile, e);
350 m_log.WarnFormat("[MAP IMAGE SERVICE]: Oops on saving {0} {1}", outputFile, e); 446 }
351 } 447 } // Save also as png?
352
353 // Save also as png?
354 448
449 output.Dispose();
355 return true; 450 return true;
356 } 451 }
357 452